blob: 6826acfd05693fab3695a87026c06630b17f6bca [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'
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200264 \ && winheight(0) == 5)
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100265
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 &&
Bram Moolenaarc05d1c02020-09-04 18:38:06 +0200270 \ winheight(0) == 7 &&
Bram Moolenaarda59dd52016-01-05 21:59:58 +0100271 \ 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
Bram Moolenaare2e40752020-09-04 21:18:46 +0200362 call assert_fails('Xfile non_existent_file', 'E40:')
Bram Moolenaar049cba92016-06-26 14:38:04 +0200363
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 Moolenaare2e40752020-09-04 21:18:46 +0200505 call assert_fails('Xprev', 'E553:')
506 call assert_fails('Xpfile', 'E553:')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +0200507 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('.'))
Bram Moolenaare2e40752020-09-04 21:18:46 +0200529 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 Moolenaare5a2dc82021-01-03 19:52:05 +0100705def Test_helpgrep_vim9_restore_cpo()
706 assert_equal('aABceFs', &cpo)
707
708 var rtp_save = &rtp
709 var dir = 'Xruntime/after'
710 &rtp ..= ',' .. dir
711 mkdir(dir .. '/ftplugin', 'p')
712 writefile(['vim9'], dir .. '/ftplugin/qf.vim')
713 filetype plugin on
714 silent helpgrep grail
715 cwindow
716 silent helpgrep grail
717
718 assert_equal('aABceFs', &cpo)
719 delete(dir, 'rf')
720 &rtp = rtp_save
721 cclose
722 helpclose
723enddef
724
Bram Moolenaar6920c722016-01-22 22:44:10 +0100725func Test_errortitle()
726 augroup QfBufWinEnter
727 au!
728 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
729 augroup END
730 copen
731 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'')'}]
732 call setqflist(a)
733 call assert_equal(':setqflist()', g:a)
734 augroup QfBufWinEnter
735 au!
736 augroup END
737 augroup! QfBufWinEnter
738endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100739
Bram Moolenaar5584df62016-03-18 21:00:51 +0100740func Test_vimgreptitle()
741 augroup QfBufWinEnter
742 au!
743 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
744 augroup END
745 try
746 vimgrep /pattern/j file
747 catch /E480/
748 endtry
749 copen
750 call assert_equal(': vimgrep /pattern/j file', g:a)
751 augroup QfBufWinEnter
752 au!
753 augroup END
754 augroup! QfBufWinEnter
755endfunc
756
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100757func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200758 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +0100759
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200760 Xgetexpr ['file:1:1:message']
761 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100762 if a:cchar == 'c'
763 call setqflist(l, 'r')
764 else
765 call setloclist(0, l, 'r')
766 endif
767
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200768 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +0100769 if a:cchar == 'c'
770 let title = ':setqflist()'
771 else
772 let title = ':setloclist()'
773 endif
774 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200775 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100776endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100777
778" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100779func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200780 call XqfTitleTests('c')
781 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100782endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100783
784" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100785func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100786 let save_efm = &efm
787 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
788 cgetexpr ['WWWW', 'EEEE', 'CCCC']
789 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
790 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
791 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
792 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
793 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
794 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
795 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
796 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
797 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100798endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100799
800" This will test for problems in quickfix:
801" A. incorrectly copying location lists which caused the location list to show
802" a different name than the file that was actually being displayed.
803" B. not reusing the window for which the location list window is opened but
804" instead creating new windows.
805" C. make sure that the location list window is not reused instead of the
806" window it belongs to.
807"
808" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100809func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100810 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
811 let word = substitute(base, '\v(.*)\..*', '\1', '')
812
813 setl modifiable
814 setl noreadonly
815 setl noswapfile
816 setl bufhidden=delete
817 %del _
818 " For problem 2:
819 " 'buftype' has to be set to reproduce the constant opening of new windows
820 setl buftype=nofile
821
822 call setline(1, word)
823
824 setl nomodified
825 setl nomodifiable
826 setl readonly
827 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100828endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100829
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100830func Test_locationlist()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200831 enew
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100832
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200833 augroup testgroup
834 au!
835 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
836 augroup END
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100837
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200838 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100839
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200840 let qflist = []
841 for word in words
842 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
843 " NOTE: problem 1:
844 " intentionally not setting 'lnum' so that the quickfix entries are not
845 " valid
846 eval qflist->setloclist(0, ' ')
847 endfor
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100848
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200849 " Test A
850 lrewind
851 enew
852 lopen
853 4lnext
854 vert split
855 wincmd L
856 lopen
857 wincmd p
858 lnext
859 let fileName = expand("%")
860 wincmd p
861 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
862 let fileName = substitute(fileName, '\\', '/', 'g')
863 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
864 call assert_equal("test://bar.txt", fileName)
865 call assert_equal("test://bar.txt", locationListFileName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100866
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200867 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100868
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200869 " Test B:
870 lrewind
871 lopen
872 2
873 exe "normal \<CR>"
874 wincmd p
875 3
876 exe "normal \<CR>"
877 wincmd p
878 4
879 exe "normal \<CR>"
880 call assert_equal(2, winnr('$'))
881 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100882
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200883 " Test C:
884 lrewind
885 lopen
886 " Let's move the location list window to the top to check whether it (the
887 " first window found) will be reused when we try to open new windows:
888 wincmd K
889 2
890 exe "normal \<CR>"
891 wincmd p
892 3
893 exe "normal \<CR>"
894 wincmd p
895 4
896 exe "normal \<CR>"
897 1wincmd w
898 call assert_equal('quickfix', &buftype)
899 2wincmd w
900 let bufferName = expand("%")
901 let bufferName = substitute(bufferName, '\\', '/', 'g')
902 call assert_equal('test://quux.txt', bufferName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100903
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200904 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100905
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200906 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100907endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100908
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100909func Test_locationlist_curwin_was_closed()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200910 augroup testgroup
911 au!
912 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
913 augroup END
Bram Moolenaar0899d692016-03-19 13:35:03 +0100914
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200915 func! R(n)
916 quit
917 endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100918
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200919 new
920 let q = []
921 call add(q, {'filename': 'test_curwin.txt' })
922 call setloclist(0, q)
923 call assert_fails('lrewind', 'E924:')
Bram Moolenaar0899d692016-03-19 13:35:03 +0100924
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200925 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100926endfunc
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100927
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100928func Test_locationlist_cross_tab_jump()
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200929 call writefile(['loclistfoo'], 'loclistfoo')
930 call writefile(['loclistbar'], 'loclistbar')
931 set switchbuf=usetab
932
933 edit loclistfoo
934 tabedit loclistbar
935 silent lgrep loclistfoo loclist*
936 call assert_equal(1, tabpagenr())
937
938 enew | only | tabonly
939 set switchbuf&vim
940 call delete('loclistfoo')
941 call delete('loclistbar')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100942endfunc
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200943
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100944" More tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100945func Test_efm1()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200946 " The 'errorformat' setting is different on non-Unix systems.
947 " This test works only on Unix-like systems.
948 CheckUnix
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100949
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200950 let l =<< trim [DATA]
951 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
952 "Xtestfile", line 6 col 19; this is an error
953 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
954 Xtestfile:9: parse error before `asd'
955 make: *** [vim] Error 1
956 in file "Xtestfile" linenr 10: there is an error
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100957
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200958 2 returned
959 "Xtestfile", line 11 col 1; this is an error
960 "Xtestfile", line 12 col 2; this is another error
961 "Xtestfile", line 14:10; this is an error in column 10
962 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
963 "Xtestfile", linenr 16: yet another problem
964 Error in "Xtestfile" at line 17:
965 x should be a dot
966 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
967 ^
968 Error in "Xtestfile" at line 18:
969 x should be a dot
970 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
971 .............^
972 Error in "Xtestfile" at line 19:
973 x should be a dot
974 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
975 --------------^
976 Error in "Xtestfile" at line 20:
977 x should be a dot
978 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
979 ^
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100980
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200981 Does anyone know what is the problem and how to correction it?
982 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
983 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
984 [DATA]
985
986 call writefile(l, 'Xerrorfile1')
987 call writefile(l[:-2], 'Xerrorfile2')
988
989 let m =<< [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +0200990 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
991 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
992 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
993 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
994 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
995 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
996 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
997 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
998 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
999 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
1000 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
1001 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
1002 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
1003 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
1004 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
1005 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1006 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1007 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1008 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1009 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
1010 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
1011[DATA]
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001012 call writefile(m, 'Xtestfile')
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001013
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001014 let save_efm = &efm
1015 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
1016 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001017
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001018 exe 'cf Xerrorfile2'
1019 clast
1020 copen
1021 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1022 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001023
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001024 exe 'cf Xerrorfile1'
1025 call assert_equal([4, 12], [line('.'), col('.')])
1026 cn
1027 call assert_equal([6, 19], [line('.'), col('.')])
1028 cn
1029 call assert_equal([9, 2], [line('.'), col('.')])
1030 cn
1031 call assert_equal([10, 2], [line('.'), col('.')])
1032 cn
1033 call assert_equal([11, 1], [line('.'), col('.')])
1034 cn
1035 call assert_equal([12, 2], [line('.'), col('.')])
1036 cn
1037 call assert_equal([14, 10], [line('.'), col('.')])
1038 cn
1039 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1040 cn
1041 call assert_equal([16, 2], [line('.'), col('.')])
1042 cn
1043 call assert_equal([17, 6], [line('.'), col('.')])
1044 cn
1045 call assert_equal([18, 7], [line('.'), col('.')])
1046 cn
1047 call assert_equal([19, 8], [line('.'), col('.')])
1048 cn
1049 call assert_equal([20, 9], [line('.'), col('.')])
1050 clast
1051 cprev
1052 cprev
1053 wincmd w
1054 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1055 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001056
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001057 let &efm = save_efm
1058 call delete('Xerrorfile1')
1059 call delete('Xerrorfile2')
1060 call delete('Xtestfile')
Bram Moolenaaree85df32017-03-19 14:19:50 +01001061endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001062
Bram Moolenaarab47c612016-06-14 22:02:26 +02001063" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001064func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001065 call s:setup_commands(a:cchar)
1066
Bram Moolenaarab47c612016-06-14 22:02:26 +02001067 let save_efm=&efm
1068 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1069
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001070 let lines = ["Entering dir 'dir1/a'",
1071 \ 'habits2.txt:1:Nine Healthy Habits',
1072 \ "Entering dir 'b'",
1073 \ 'habits3.txt:2:0 Hours of television',
1074 \ 'habits2.txt:7:5 Small meals',
1075 \ "Entering dir 'dir1/c'",
1076 \ 'habits4.txt:3:1 Hour of exercise',
1077 \ "Leaving dir 'dir1/c'",
1078 \ "Leaving dir 'dir1/a'",
1079 \ 'habits1.txt:4:2 Liters of water',
1080 \ "Entering dir 'dir2'",
1081 \ 'habits5.txt:5:3 Cups of hot green tea',
1082 \ "Leaving dir 'dir2'"
1083 \]
Bram Moolenaarab47c612016-06-14 22:02:26 +02001084
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001085 Xexpr ""
1086 for l in lines
1087 Xaddexpr l
1088 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001089
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001090 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001091
1092 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1093 call assert_equal(1, qf[1].lnum)
1094 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1095 call assert_equal(2, qf[3].lnum)
1096 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1097 call assert_equal(7, qf[4].lnum)
1098 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1099 call assert_equal(3, qf[6].lnum)
1100 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1101 call assert_equal(4, qf[9].lnum)
1102 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1103 call assert_equal(5, qf[11].lnum)
1104
1105 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001106endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001107
1108" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001109func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001110 " Create the directory stack and files
1111 call mkdir('dir1')
1112 call mkdir('dir1/a')
1113 call mkdir('dir1/a/b')
1114 call mkdir('dir1/c')
1115 call mkdir('dir2')
1116
1117 let lines = ["Nine Healthy Habits",
1118 \ "0 Hours of television",
1119 \ "1 Hour of exercise",
1120 \ "2 Liters of water",
1121 \ "3 Cups of hot green tea",
1122 \ "4 Short mental breaks",
1123 \ "5 Small meals",
1124 \ "6 AM wake up time",
1125 \ "7 Minutes of laughter",
1126 \ "8 Hours of sleep (at least)",
1127 \ "9 PM end of the day and off to bed"
1128 \ ]
1129 call writefile(lines, 'habits1.txt')
1130 call writefile(lines, 'dir1/a/habits2.txt')
1131 call writefile(lines, 'dir1/a/b/habits3.txt')
1132 call writefile(lines, 'dir1/c/habits4.txt')
1133 call writefile(lines, 'dir2/habits5.txt')
1134
1135 call s:dir_stack_tests('c')
1136 call s:dir_stack_tests('l')
1137
1138 call delete('dir1', 'rf')
1139 call delete('dir2', 'rf')
1140 call delete('habits1.txt')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001141endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001142
Bram Moolenaar9b457942016-10-09 16:10:05 +02001143" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001144func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001145 call s:setup_commands(a:cchar)
1146
1147 let save_efm = &efm
1148
1149 let &efm =
1150 \ '%Eerror %m %l,' .
1151 \ '%-Wignored %m %l,' .
1152 \ '%+Cmore ignored %m %l,' .
1153 \ '%Zignored end'
1154 Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
1155 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1156 call assert_equal([['resync', 1, 4, 'E']], l)
1157
1158 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001159endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001160
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001161func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001162 call Xefm_ignore_continuations('c')
1163 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001164endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001165
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001166" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001167func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001168 call s:setup_commands(a:cchar)
1169
Bram Moolenaar049cba92016-06-26 14:38:04 +02001170 let save_efm = &efm
1171
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001172 set efm=%f:%l:%m,%f:%f:%l:%m
1173 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1174
1175 set efm=%f:%l:%m,%f:%l:%r:%m
1176 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1177
1178 set efm=%f:%l:%m,%O:%f:%l:%m
1179 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1180
1181 set efm=%f:%l:%m,%f:%l:%*[^a-z
1182 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1183
1184 set efm=%f:%l:%m,%f:%l:%*c
1185 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1186
1187 set efm=%f:%l:%m,%L%M%N
1188 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1189
1190 set efm=%f:%l:%m,%f:%l:%m:%R
1191 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1192
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001193 " Invalid regular expression
1194 set efm=%\\%%k
1195 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1196
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001197 set efm=
1198 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1199
1200 set efm=%DEntering\ dir\ abc,%f:%l:%m
1201 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
1202
1203 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001204endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001205
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001206func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001207 call Xinvalid_efm_Tests('c')
1208 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001209endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001210
1211" TODO:
1212" Add tests for the following formats in 'errorformat'
1213" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001214func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001215 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001216
1217 " Test for %s format in efm
1218 set efm=%f:%s
1219 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001220 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001221 call assert_equal('^\VLine search text\$', l[0].pattern)
1222 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001223
Bram Moolenaaree85df32017-03-19 14:19:50 +01001224 let l = split(execute('clist', ''), "\n")
1225 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1226
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001227 " Test for a long line
1228 cexpr 'Xtestfile:' . repeat('a', 1026)
1229 let l = getqflist()
1230 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1231
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001232 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001233 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001234 [Xtestfile1]
1235 (1,17) error: ';' missing
1236 (21,2) warning: variable 'z' not defined
1237 (67,3) error: end of file found before string ended
1238 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001239
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001240 [Xtestfile2]
1241 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001242
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001243 [Xtestfile3]
1244 NEW compiler v1.1
1245 (2,2) warning: variable 'x' not defined
1246 (67,3) warning: 's' already defined
1247 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001248 [DATA]
1249
Bram Moolenaaree85df32017-03-19 14:19:50 +01001250 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001251 " To exercise the push/pop file functionality in quickfix, the test files
1252 " need to be created.
1253 call writefile(['Line1'], 'Xtestfile1')
1254 call writefile(['Line2'], 'Xtestfile2')
1255 call writefile(['Line3'], 'Xtestfile3')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001256 cexpr ""
1257 for l in lines
1258 caddexpr l
1259 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001260 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001261 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001262 call assert_equal(21, l[2].lnum)
1263 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001264 call assert_equal('w', l[2].type)
1265 call assert_equal('e', l[3].type)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001266 call delete('Xtestfile1')
1267 call delete('Xtestfile2')
1268 call delete('Xtestfile3')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001269
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001270 " Test for %P, %Q with non-existing files
1271 cexpr lines
1272 let l = getqflist()
1273 call assert_equal(14, len(l))
1274 call assert_equal('[Xtestfile1]', l[0].text)
1275 call assert_equal('[Xtestfile2]', l[6].text)
1276 call assert_equal('[Xtestfile3]', l[9].text)
1277
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001278 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001279 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001280 Error 275
1281 line 42
1282 column 3
1283 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001284 [DATA]
1285
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001286 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1287 cgetexpr lines
1288 let l = getqflist()
1289 call assert_equal(275, l[0].nr)
1290 call assert_equal(42, l[0].lnum)
1291 call assert_equal(3, l[0].col)
1292 call assert_equal('E', l[0].type)
1293 call assert_equal("\n' ' expected after '--'", l[0].text)
1294
1295 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001296 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001297 Error in line 147 of foo.c:
1298 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001299 [DATA]
1300
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001301 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1302 cgetexpr lines
1303 let l = getqflist()
1304 call assert_equal(147, l[0].lnum)
1305 call assert_equal('E', l[0].type)
1306 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001307
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001308 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001309 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001310 ==============================================================
1311 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1312 --------------------------------------------------------------
1313 Traceback (most recent call last):
1314 File "unittests/dbfacadeTest.py", line 89, in testFoo
1315 self.assertEquals(34, dtid)
1316 File "/usr/lib/python2.2/unittest.py", line 286, in
1317 failUnlessEqual
1318 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001319 W:AssertionError: 34 != 33
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001320
1321 --------------------------------------------------------------
1322 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001323 [DATA]
1324
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001325 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001326 cgetexpr lines
1327 let l = getqflist()
1328 call assert_equal(8, len(l))
1329 call assert_equal(89, l[4].lnum)
1330 call assert_equal(1, l[4].valid)
1331 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001332 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001333
Bram Moolenaard76ce852018-05-01 15:02:04 +02001334 " Test for %o
1335 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001336 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
1337 call writefile(['Line1'], 'Xotestfile')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001338 let l = getqflist()
1339 call assert_equal(1, len(l), string(l))
1340 call assert_equal('Language.PureScript.Types', l[0].module)
1341 copen
1342 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1343 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001344 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001345 cclose
1346 bd
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001347 call delete("Xotestfile")
Bram Moolenaard76ce852018-05-01 15:02:04 +02001348
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001349 " Test for a long module name
1350 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1351 let l = getqflist()
1352 call assert_equal(repeat('m', 1024), l[0].module)
1353 call assert_equal(15, l[0].lnum)
1354 call assert_equal('message', l[0].text)
1355
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001356 " The following sequence of commands used to crash Vim
1357 set efm=%W%m
1358 cgetexpr ['msg1']
1359 let l = getqflist()
1360 call assert_equal(1, len(l), string(l))
1361 call assert_equal('msg1', l[0].text)
1362 set efm=%C%m
1363 lexpr 'msg2'
1364 let l = getloclist(0)
1365 call assert_equal(1, len(l), string(l))
1366 call assert_equal('msg2', l[0].text)
1367 lopen
1368 call setqflist([], 'r')
1369 caddbuf
1370 let l = getqflist()
1371 call assert_equal(1, len(l), string(l))
1372 call assert_equal('|| msg2', l[0].text)
1373
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001374 " When matching error lines, case should be ignored. Test for this.
1375 set noignorecase
1376 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1377 call assert_equal(10, l.items[0].lnum)
1378 call assert_equal('Line 20', l.items[0].text)
1379 set ignorecase&
1380
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001381 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001382 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001383endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001384
Bram Moolenaare9283662020-06-07 14:10:47 +02001385" Test for '%t' (error type) field in 'efm'
1386func Test_efm_error_type()
1387 let save_efm = &efm
1388
1389 " error type
1390 set efm=%f:%l:%t:%m
1391 cexpr ["Xfile1:10:E:msg1", "Xfile1:20:W:msg2", "Xfile1:30:I:msg3",
1392 \ "Xfile1:40:N:msg4", "Xfile1:50:R:msg5"]
1393 let output = split(execute('clist'), "\n")
1394 call assert_equal([
1395 \ ' 1 Xfile1:10 error: msg1',
1396 \ ' 2 Xfile1:20 warning: msg2',
1397 \ ' 3 Xfile1:30 info: msg3',
1398 \ ' 4 Xfile1:40 note: msg4',
1399 \ ' 5 Xfile1:50 R: msg5'], output)
1400
1401 " error type and a error number
1402 set efm=%f:%l:%t:%n:%m
1403 cexpr ["Xfile1:10:E:2:msg1", "Xfile1:20:W:4:msg2", "Xfile1:30:I:6:msg3",
1404 \ "Xfile1:40:N:8:msg4", "Xfile1:50:R:3:msg5"]
1405 let output = split(execute('clist'), "\n")
1406 call assert_equal([
1407 \ ' 1 Xfile1:10 error 2: msg1',
1408 \ ' 2 Xfile1:20 warning 4: msg2',
1409 \ ' 3 Xfile1:30 info 6: msg3',
1410 \ ' 4 Xfile1:40 note 8: msg4',
1411 \ ' 5 Xfile1:50 R 3: msg5'], output)
1412 let &efm = save_efm
1413endfunc
1414
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001415func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001416 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001417 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001418 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001419 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001420 colder
1421 cgetexpr []
1422 endfunc
1423 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001424 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001425 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001426 lolder
1427 lgetexpr []
1428 endfunc
1429 endif
1430
1431 augroup testgroup
1432 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001433 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001434 augroup END
1435
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001436 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001437 let words = [ "a", "b" ]
1438 let qflist = []
1439 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001440 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001441 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001442 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001443 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001444
1445 augroup! testgroup
1446endfunc
1447
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001448func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001449 call XquickfixChangedByAutocmd('c')
1450 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001451endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001452
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001453func Test_setloclist_in_autocommand()
1454 call writefile(['test1', 'test2'], 'Xfile')
1455 edit Xfile
1456 let s:bufnr = bufnr()
1457 call setloclist(1,
1458 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1459 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}])
1460
1461 augroup Test_LocList
1462 au!
1463 autocmd BufEnter * call setloclist(1,
1464 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1465 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}], 'r')
1466 augroup END
1467
1468 lopen
1469 call assert_fails('exe "normal j\<CR>"', 'E926:')
1470
1471 augroup Test_LocList
1472 au!
1473 augroup END
1474 call delete('Xfile')
1475endfunc
1476
Bram Moolenaar8b201792016-03-25 15:01:10 +01001477func Test_caddbuffer_to_empty()
1478 helpgr quickfix
1479 call setqflist([], 'r')
1480 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001481 try
1482 cn
1483 catch
1484 " number of matches is unknown
1485 call assert_true(v:exception =~ 'E553:')
1486 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001487 quit!
1488endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001489
1490func Test_cgetexpr_works()
1491 " this must not crash Vim
1492 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001493 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001494endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001495
1496" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001497func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001498 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001499
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001500 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001501 \ {'bufnr': a:bnum, 'lnum': 2}])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001502 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001503 call assert_equal(2, len(l))
1504 call assert_equal(2, l[1].lnum)
1505
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001506 Xnext
1507 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1508 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001509 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001510 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001511 call assert_equal(3, line('.'))
1512
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001513 " Appending entries to the list should not change the cursor position
1514 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001515 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001516 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001517 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001518 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1519 call assert_equal(1, line('.'))
1520 close
1521
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001522 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001523 \ {'bufnr': a:bnum, 'lnum': 4},
1524 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001525 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001526 call assert_equal(3, len(l))
1527 call assert_equal(5, l[2].lnum)
1528
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001529 call g:Xsetlist([])
1530 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001531 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001532
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001533 " Tests for setting the 'valid' flag
1534 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1535 Xwindow
1536 call assert_equal(1, winnr('$'))
1537 let l = g:Xgetlist()
1538 call g:Xsetlist(l)
1539 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001540 " Adding a non-valid entry should not mark the list as having valid entries
1541 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1542 Xwindow
1543 call assert_equal(1, winnr('$'))
1544
1545 " :cnext/:cprev should still work even with invalid entries in the list
1546 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1547 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1548 call g:Xsetlist(l)
1549 Xnext
1550 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1551 Xprev
1552 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1553 " :cnext/:cprev should still work after appending invalid entries to an
1554 " empty list
1555 call g:Xsetlist([])
1556 call g:Xsetlist(l, 'a')
1557 Xnext
1558 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1559 Xprev
1560 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1561
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001562 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1563 Xwindow
1564 call assert_equal(2, winnr('$'))
1565 Xclose
1566 let save_efm = &efm
1567 set efm=%m
1568 Xgetexpr 'TestMessage'
1569 let l = g:Xgetlist()
1570 call g:Xsetlist(l)
1571 call assert_equal(1, g:Xgetlist()[0].valid)
1572 let &efm = save_efm
1573
Bram Moolenaaree85df32017-03-19 14:19:50 +01001574 " Error cases:
1575 " Refer to a non-existing buffer and pass a non-dictionary type
1576 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1577 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1578 call g:Xsetlist([[1, 2,3]])
1579 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001580 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001581endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001582
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001583func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001584 new Xtestfile | only
1585 let bnum = bufnr('%')
1586 call setline(1, range(1,5))
1587
1588 call SetXlistTests('c', bnum)
1589 call SetXlistTests('l', bnum)
1590
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001591 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001592 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001593endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001594
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001595func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001596 call s:setup_commands(a:cchar)
1597
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001598 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001599 let @/ = 'Test_'
1600 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001601 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001602 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001603 Xvimgrep empty test_quickfix.vim
1604 call assert_true(len(g:Xgetlist()) > 0)
1605 Xvimgrep matches test_quickfix.vim
1606 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001607 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001608 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001609 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001610 call g:Xsetlist([], 'r')
1611 call assert_true(len(g:Xgetlist()) == 0)
1612 Xolder
1613 call assert_equal(testlen, len(g:Xgetlist()))
1614 Xnewer
1615 Xnewer
1616 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001617endfunc
1618
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001619func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001620 call Xlist_empty_middle('c')
1621 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001622endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001623
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001624func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001625 call s:setup_commands(a:cchar)
1626
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001627 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001628 Xvimgrep one test_quickfix.vim
1629 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001630 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001631 Xvimgrep two test_quickfix.vim
1632 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001633 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001634 Xvimgrep three test_quickfix.vim
1635 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001636 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001637 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001638 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001639 call g:Xsetlist([], 'r')
1640 call assert_true(len(g:Xgetlist()) == 0)
1641 Xnewer
1642 call assert_equal(twolen, len(g:Xgetlist()))
1643 Xnewer
1644 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001645endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001646
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001647func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001648 call Xlist_empty_older('c')
1649 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001650endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001651
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001652func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001653 call s:setup_commands(a:cchar)
1654
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001655 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1656 \ {'filename': 'fnameB', 'text': 'B'}]
1657 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1658 \ {'filename': 'fnameD', 'text': 'D'},
1659 \ {'filename': 'fnameE', 'text': 'E'}]
1660
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001661 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001662 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001663 silent! Xnewer 99
1664 call g:Xsetlist(list1)
1665 call g:Xsetlist(list2)
1666 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001667 call assert_equal(3, len(li))
1668 call assert_equal('C', li[0]['text'])
1669 call assert_equal('D', li[1]['text'])
1670 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001671 silent! Xolder
1672 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001673 call assert_equal(2, len(li))
1674 call assert_equal('A', li[0]['text'])
1675 call assert_equal('B', li[1]['text'])
1676
1677 " {action} is specified ' '.
1678 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001679 silent! Xnewer 99
1680 call g:Xsetlist(list1)
1681 call g:Xsetlist(list2, ' ')
1682 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001683 call assert_equal(3, len(li))
1684 call assert_equal('C', li[0]['text'])
1685 call assert_equal('D', li[1]['text'])
1686 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001687 silent! Xolder
1688 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001689 call assert_equal(2, len(li))
1690 call assert_equal('A', li[0]['text'])
1691 call assert_equal('B', li[1]['text'])
1692
1693 " {action} is specified 'a'.
1694 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001695 silent! Xnewer 99
1696 call g:Xsetlist(list1)
1697 call g:Xsetlist(list2, 'a')
1698 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001699 call assert_equal(5, len(li))
1700 call assert_equal('A', li[0]['text'])
1701 call assert_equal('B', li[1]['text'])
1702 call assert_equal('C', li[2]['text'])
1703 call assert_equal('D', li[3]['text'])
1704 call assert_equal('E', li[4]['text'])
1705
1706 " {action} is specified 'r'.
1707 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001708 silent! Xnewer 99
1709 call g:Xsetlist(list1)
1710 call g:Xsetlist(list2, 'r')
1711 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001712 call assert_equal(3, len(li))
1713 call assert_equal('C', li[0]['text'])
1714 call assert_equal('D', li[1]['text'])
1715 call assert_equal('E', li[2]['text'])
1716
1717 " Test for wrong value.
1718 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001719 call assert_fails("call g:Xsetlist(0)", 'E714:')
1720 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1721 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1722 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1723 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001724endfunc
1725
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001726func Test_setqflist_invalid_nr()
1727 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02001728 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001729endfunc
1730
Bram Moolenaar99234f22020-02-10 22:56:54 +01001731func Test_setqflist_user_sets_buftype()
1732 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
1733 set buftype=quickfix
1734 call setqflist([], 'a')
1735 enew
1736endfunc
1737
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001738func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001739 call XquickfixSetListWithAct('c')
1740 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001741endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001742
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001743func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001744 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001745
Bram Moolenaar049cba92016-06-26 14:38:04 +02001746 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001747 call assert_equal(1, l[0].lnum)
1748 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001749 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001750 call assert_equal(2, l[1].lnum)
1751 call assert_equal(1, l[1].col)
1752 call assert_equal(4070, len(l[1].text))
1753 call assert_equal(3, l[2].lnum)
1754 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001755 call assert_equal(4070, len(l[2].text))
1756 call assert_equal(4, l[3].lnum)
1757 call assert_equal(1, l[3].col)
1758 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001759
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001760 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001761endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001762
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001763func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001764 call s:setup_commands(a:cchar)
1765
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001766 let testfile = 'samples/quickfix.txt'
1767
1768 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001769 exe 'Xgetfile' testfile
1770 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001771
1772 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001773 Xexpr readfile(testfile)
1774 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001775
1776 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001777 Xexpr join(readfile(testfile), "\n")
1778 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001779
1780 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001781 exe 'edit' testfile
1782 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02001783 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001784endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001785
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001786func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001787 call s:long_lines_tests('c')
1788 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001789endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001790
Bram Moolenaar59941cb2020-09-05 17:03:40 +02001791func Test_cgetfile_on_long_lines()
1792 " Problematic values if the line is longer than 4096 bytes. Then 1024 bytes
1793 " are read at a time.
1794 for len in [4078, 4079, 4080, 5102, 5103, 5104, 6126, 6127, 6128, 7150, 7151, 7152]
1795 let lines = [
1796 \ '/tmp/file1:1:1:aaa',
1797 \ '/tmp/file2:1:1:%s',
1798 \ '/tmp/file3:1:1:bbb',
1799 \ '/tmp/file4:1:1:ccc',
1800 \ ]
1801 let lines[1] = substitute(lines[1], '%s', repeat('x', len), '')
1802 call writefile(lines, 'Xcqetfile.txt')
1803 cgetfile Xcqetfile.txt
1804 call assert_equal(4, getqflist(#{size: v:true}).size, 'with length ' .. len)
1805 endfor
1806 call delete('Xcqetfile.txt')
1807endfunc
1808
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001809func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001810 let l = []
1811 for i in range(1, 20)
1812 call add(l, 'Line' . i)
1813 endfor
1814 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001815endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001816
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001817func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001818 call s:create_test_file('Xqftestfile1')
1819 call s:create_test_file('Xqftestfile2')
1820 call s:create_test_file('Xqftestfile3')
1821
1822 new | only
1823 edit Xqftestfile1
1824 let file1_winid = win_getid()
1825 new Xqftestfile2
1826 let file2_winid = win_getid()
1827 cgetexpr ['Xqftestfile1:5:Line5',
1828 \ 'Xqftestfile1:6:Line6',
1829 \ 'Xqftestfile2:10:Line10',
1830 \ 'Xqftestfile2:11:Line11',
1831 \ 'Xqftestfile3:15:Line15',
1832 \ 'Xqftestfile3:16:Line16']
1833
1834 new
1835 let winid = win_getid()
1836 cfirst | cnext
1837 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001838 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001839 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001840 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001841 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001842
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001843 " Test for 'switchbuf' set to search for files in windows in the current
1844 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001845 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001846 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02001847 cfirst | cnext
1848 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001849 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001850 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001851 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001852 call assert_equal(file2_winid, win_getid())
1853
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001854 " Test for 'switchbuf' set to search for files in tabpages and jump to an
1855 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001856 enew | only
1857 set switchbuf=usetab
1858 tabedit Xqftestfile1
1859 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01001860 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02001861 tabfirst
1862 cfirst | cnext
1863 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001864 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001865 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01001866 6cnext
1867 call assert_equal(4, tabpagenr())
1868 2cpfile
1869 call assert_equal(2, tabpagenr())
1870 2cnfile
1871 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001872 tabfirst | tabonly | enew
1873
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001874 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001875 set switchbuf=split
1876 cfirst | cnext
1877 call assert_equal(1, winnr('$'))
1878 cnext | cnext
1879 call assert_equal(2, winnr('$'))
1880 cnext | cnext
1881 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001882
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001883 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001884 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001885 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001886 cfirst | cnext
1887 call assert_equal(1, tabpagenr('$'))
1888 cnext | cnext
1889 call assert_equal(2, tabpagenr('$'))
1890 cnext | cnext
1891 call assert_equal(3, tabpagenr('$'))
1892 tabfirst | enew | tabonly | only
1893
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01001894 set switchbuf=uselast
1895 split
1896 let last_winid = win_getid()
1897 copen
1898 exe "normal 1G\<CR>"
1899 call assert_equal(last_winid, win_getid())
1900 enew | only
1901
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001902 " With an empty 'switchbuf', jumping to a quickfix entry should open the
1903 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001904 set switchbuf=
1905 edit Xqftestfile1
1906 let file1_winid = win_getid()
1907 new Xqftestfile2
1908 let file2_winid = win_getid()
1909 copen
1910 exe "normal 1G\<CR>"
1911 call assert_equal(file1_winid, win_getid())
1912 copen
1913 exe "normal 3G\<CR>"
1914 call assert_equal(file2_winid, win_getid())
1915 copen | only
1916 exe "normal 5G\<CR>"
1917 call assert_equal(2, winnr('$'))
1918 call assert_equal(1, bufwinnr('Xqftestfile3'))
1919
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001920 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02001921 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02001922 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001923 set switchbuf=usetab
1924 tabedit Xqftestfile1
1925 tabedit Xqftestfile2
1926 tabedit Xqftestfile3
1927 tabfirst
1928 copen | only
1929 clast
1930 call assert_equal(4, tabpagenr())
1931 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001932
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001933 " Jumping to a file that is not present in any of the tabpages and the
1934 " current tabpage doesn't have any usable windows, should open it in a new
1935 " window in the current tabpage.
1936 copen | only
1937 cfirst
1938 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001939 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001940
1941 " If opening a file changes 'switchbuf', then the new value should be
1942 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02001943 set modeline&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001944 call writefile(["vim: switchbuf=split"], 'Xqftestfile1')
1945 enew | only
1946 set switchbuf&vim
1947 cexpr "Xqftestfile1:1:10"
1948 call assert_equal('split', &switchbuf)
1949 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
1950 enew | only
1951 set switchbuf=useopen
1952 cexpr "Xqftestfile1:1:10"
1953 call assert_equal('usetab', &switchbuf)
1954 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
1955 enew | only
1956 set switchbuf=useopen
1957 cexpr "Xqftestfile1:1:10"
1958 call assert_equal('', &switchbuf)
1959
Bram Moolenaar049cba92016-06-26 14:38:04 +02001960 call delete('Xqftestfile1')
1961 call delete('Xqftestfile2')
1962 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001963 set switchbuf&vim
1964
1965 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001966endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001967
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001968func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001969 call s:setup_commands(a:cchar)
1970
1971 enew | only
1972
Bram Moolenaarc1542742016-07-20 21:44:37 +02001973 let fname = 'Xqftestfile' . a:cchar
1974 call s:create_test_file(fname)
1975 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02001976
Bram Moolenaarc1542742016-07-20 21:44:37 +02001977 Xgetexpr [fname . ':5:Line5',
1978 \ fname . ':10:Line10',
1979 \ fname . ':15:Line15',
1980 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02001981
1982 6,14delete
1983 call append(6, ['Buffer', 'Window'])
1984
1985 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001986 call assert_equal(5, l[0].lnum)
1987 call assert_equal(6, l[2].lnum)
1988 call assert_equal(13, l[3].lnum)
1989
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001990 " If a file doesn't have any quickfix entries, then deleting lines in the
1991 " file should not update the quickfix list
1992 call g:Xsetlist([], 'f')
1993 1,2delete
1994 call assert_equal([], g:Xgetlist())
1995
Bram Moolenaar049cba92016-06-26 14:38:04 +02001996 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02001997 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001998endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001999
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002000func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02002001 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002002 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02002003 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002004 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002005endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002006
2007" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002008func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002009 call s:setup_commands(a:cchar)
2010
2011 " The following lines are used for the grep test. Don't remove.
2012 " Grep_Test_Text: Match 1
2013 " Grep_Test_Text: Match 2
2014 " GrepAdd_Test_Text: Match 1
2015 " GrepAdd_Test_Text: Match 2
2016 enew! | only
2017 set makeef&vim
2018 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002019 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002020 Xopen
2021 call assert_true(w:quickfix_title =~ '^:grep')
2022 Xclose
2023 enew
2024 set makeef=Temp_File_##
2025 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002026 call assert_true(len(g:Xgetlist()) == 9)
2027
2028 " Try with 'grepprg' set to 'internal'
2029 set grepprg=internal
2030 silent Xgrep Grep_Test_Text: test_quickfix.vim
2031 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
2032 call assert_true(len(g:Xgetlist()) == 9)
2033 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002034
2035 call writefile(['Vim'], 'XtestTempFile')
2036 set makeef=XtestTempFile
2037 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002038 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002039 call assert_false(filereadable('XtestTempFile'))
2040 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002041endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002042
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002043func Test_grep()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002044 " The grepprg may not be set on non-Unix systems
2045 CheckUnix
Bram Moolenaar049cba92016-06-26 14:38:04 +02002046
2047 call s:test_xgrep('c')
2048 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002049endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002050
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002051func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002052 " Use one 'errorformat' for two windows. Add an expression to each of them,
2053 " make sure they each keep their own state.
2054 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
2055 call mkdir('Xone/a', 'p')
2056 call mkdir('Xtwo/a', 'p')
2057 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2058 call writefile(lines, 'Xone/a/one.txt')
2059 call writefile(lines, 'Xtwo/a/two.txt')
2060
2061 new one
2062 let one_id = win_getid()
2063 lexpr ""
2064 new two
2065 let two_id = win_getid()
2066 lexpr ""
2067
2068 laddexpr "Entering dir 'Xtwo/a'"
2069 call win_gotoid(one_id)
2070 laddexpr "Entering dir 'Xone/a'"
2071 call win_gotoid(two_id)
2072 laddexpr 'two.txt:5:two two two'
2073 call win_gotoid(one_id)
2074 laddexpr 'one.txt:3:one one one'
2075
2076 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002077 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2078 call assert_equal(3, loc_one[1].lnum)
2079
2080 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002081 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2082 call assert_equal(5, loc_two[1].lnum)
2083
2084 call win_gotoid(one_id)
2085 bwipe!
2086 call win_gotoid(two_id)
2087 bwipe!
2088 call delete('Xone', 'rf')
2089 call delete('Xtwo', 'rf')
2090endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002091
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002092func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002093 call s:setup_commands(a:cchar)
2094
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002095 " Calling lbottom without any errors should fail
2096 if a:cchar == 'l'
2097 call assert_fails('lbottom', 'E776:')
2098 endif
2099
Bram Moolenaar875feea2017-06-11 16:07:51 +02002100 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002101 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002102 let wid = win_getid()
2103 call assert_equal(1, line('.'))
2104 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002105 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002106 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002107 call win_gotoid(wid)
2108 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002109 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002110endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002111
2112" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002113func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002114 call XbottomTests('c')
2115 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002116endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002117
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002118func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002119 call s:setup_commands(a:cchar)
2120
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002121 " clear all lists after the first one, then replace the first one.
2122 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002123 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002124 let entry = {'filename': 'foo', 'lnum': 42}
2125 call g:Xsetlist([entry], 'r')
2126 call g:Xsetlist([entry, entry])
2127 call g:Xsetlist([entry, entry, entry])
2128 let res = split(execute(a:cchar . 'hist'), "\n")
2129 call assert_equal(3, len(res))
2130 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2131 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2132 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2133 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002134
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002135 " Test for changing the quickfix lists
2136 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2137 exe '1' . a:cchar . 'hist'
2138 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2139 exe '3' . a:cchar . 'hist'
2140 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2141 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2142 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2143
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002144 call g:Xsetlist([], 'f')
2145 let l = split(execute(a:cchar . 'hist'), "\n")
2146 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002147 if a:cchar == 'c'
2148 call assert_fails('4chist', 'E16:')
2149 else
2150 call assert_fails('4lhist', 'E776:')
2151 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002152
2153 " An empty list should still show the stack history
2154 call g:Xsetlist([])
2155 let res = split(execute(a:cchar . 'hist'), "\n")
2156 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2157
2158 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002159endfunc
2160
2161func Test_history()
2162 call HistoryTest('c')
2163 call HistoryTest('l')
2164endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002165
2166func Test_duplicate_buf()
2167 " make sure we can get the highest buffer number
2168 edit DoesNotExist
2169 edit DoesNotExist2
2170 let last_buffer = bufnr("$")
2171
2172 " make sure only one buffer is created
2173 call writefile(['this one', 'that one'], 'Xgrepthis')
2174 vimgrep one Xgrepthis
2175 vimgrep one Xgrepthis
2176 call assert_equal(last_buffer + 1, bufnr("$"))
2177
2178 call delete('Xgrepthis')
2179endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002180
2181" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002182func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002183 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002184
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002185 " Error cases
2186 call assert_fails('call g:Xgetlist(99)', 'E715:')
2187 call assert_fails('call g:Xsetlist(99)', 'E714:')
2188 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002189
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002190 " Set and get the title
2191 call g:Xsetlist([])
2192 Xopen
2193 wincmd p
2194 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2195 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2196 call assert_equal(0, s)
2197 let d = g:Xgetlist({"title":1})
2198 call assert_equal('Sample', d.title)
2199 " Try setting title to a non-string value
2200 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2201 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2202
2203 Xopen
2204 call assert_equal('Sample', w:quickfix_title)
2205 Xclose
2206
2207 " Tests for action argument
2208 silent! Xolder 999
2209 let qfnr = g:Xgetlist({'all':1}).nr
2210 call g:Xsetlist([], 'r', {'title' : 'N1'})
2211 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2212 call g:Xsetlist([], ' ', {'title' : 'N2'})
2213 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2214
2215 let res = g:Xgetlist({'nr': 0})
2216 call assert_equal(qfnr + 1, res.nr)
2217 call assert_equal(['nr'], keys(res))
2218
2219 call g:Xsetlist([], ' ', {'title' : 'N3'})
2220 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2221
2222 " Changing the title of an earlier quickfix list
2223 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2224 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2225
2226 " Changing the title of an invalid quickfix list
2227 call assert_equal(-1, g:Xsetlist([], ' ',
2228 \ {'title' : 'SomeTitle', 'nr' : 99}))
2229 call assert_equal(-1, g:Xsetlist([], ' ',
2230 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2231
2232 if a:cchar == 'c'
2233 copen
2234 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2235 cclose
2236 endif
2237
2238 " Invalid arguments
Bram Moolenaare2e40752020-09-04 21:18:46 +02002239 call assert_fails('call g:Xgetlist([])', 'E715:')
2240 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002241 let s = g:Xsetlist([], 'a', {'abc':1})
2242 call assert_equal(-1, s)
2243
2244 call assert_equal({}, g:Xgetlist({'abc':1}))
2245 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2246 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2247
2248 if a:cchar == 'l'
2249 call assert_equal({}, getloclist(99, {'title': 1}))
2250 endif
2251
2252 " Context related tests
2253 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2254 call assert_equal(0, s)
2255 call test_garbagecollect_now()
2256 let d = g:Xgetlist({'context':1})
2257 call assert_equal([1,2,3], d.context)
2258 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2259 let d = g:Xgetlist({'context':1})
2260 call assert_equal({'color':'green'}, d.context)
2261 call g:Xsetlist([], 'a', {'context':"Context info"})
2262 let d = g:Xgetlist({'context':1})
2263 call assert_equal("Context info", d.context)
2264 call g:Xsetlist([], 'a', {'context':246})
2265 let d = g:Xgetlist({'context':1})
2266 call assert_equal(246, d.context)
2267 " set other Vim data types as context
2268 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2269 if has('channel')
2270 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2271 endif
2272 if has('job')
2273 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2274 endif
2275 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2276 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2277 call g:Xsetlist([], 'a', {'context' : ''})
2278 call test_garbagecollect_now()
2279 if a:cchar == 'l'
2280 " Test for copying context across two different location lists
2281 new | only
2282 let w1_id = win_getid()
2283 let l = [1]
2284 call setloclist(0, [], 'a', {'context':l})
2285 new
2286 let w2_id = win_getid()
2287 call add(l, 2)
2288 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2289 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2290 unlet! l
2291 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2292 only
2293 call setloclist(0, [], 'f')
2294 call assert_equal('', getloclist(0, {'context':1}).context)
2295 endif
2296
2297 " Test for changing the context of previous quickfix lists
2298 call g:Xsetlist([], 'f')
2299 Xexpr "One"
2300 Xexpr "Two"
2301 Xexpr "Three"
2302 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2303 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2304 " Also, check for setting the context using quickfix list number zero.
2305 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2306 call test_garbagecollect_now()
2307 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2308 call assert_equal([1], l.context)
2309 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2310 call assert_equal([2], l.context)
2311 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2312 call assert_equal([3], l.context)
2313
2314 " Test for changing the context through reference and for garbage
2315 " collection of quickfix context
2316 let l = ["red"]
2317 call g:Xsetlist([], ' ', {'context' : l})
2318 call add(l, "blue")
2319 let x = g:Xgetlist({'context' : 1})
2320 call add(x.context, "green")
2321 call assert_equal(["red", "blue", "green"], l)
2322 call assert_equal(["red", "blue", "green"], x.context)
2323 unlet l
2324 call test_garbagecollect_now()
2325 let m = g:Xgetlist({'context' : 1})
2326 call assert_equal(["red", "blue", "green"], m.context)
2327
2328 " Test for setting/getting items
2329 Xexpr ""
2330 let qfprev = g:Xgetlist({'nr':0})
2331 let s = g:Xsetlist([], ' ', {'title':'Green',
2332 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2333 call assert_equal(0, s)
2334 let qfcur = g:Xgetlist({'nr':0})
2335 call assert_true(qfcur.nr == qfprev.nr + 1)
2336 let l = g:Xgetlist({'items':1})
2337 call assert_equal('F1', bufname(l.items[0].bufnr))
2338 call assert_equal(10, l.items[0].lnum)
2339 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2340 \ {'filename':'F2', 'lnum':30}]})
2341 let l = g:Xgetlist({'items':1})
2342 call assert_equal('F2', bufname(l.items[2].bufnr))
2343 call assert_equal(30, l.items[2].lnum)
2344 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2345 let l = g:Xgetlist({'items':1})
2346 call assert_equal('F3', bufname(l.items[0].bufnr))
2347 call assert_equal(40, l.items[0].lnum)
2348 call g:Xsetlist([], 'r', {'items' : []})
2349 let l = g:Xgetlist({'items':1})
2350 call assert_equal(0, len(l.items))
2351
2352 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2353 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2354 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2355 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2356
2357 " Test for getting id of window associated with a location list window
2358 if a:cchar == 'l'
2359 only
2360 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2361 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002362 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002363 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2364 wincmd w
2365 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2366 only
2367 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002368
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002369 " The following used to crash Vim with address sanitizer
2370 call g:Xsetlist([], 'f')
2371 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2372 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002373
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002374 " Try setting the items using a string
2375 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002376
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002377 " Save and restore the quickfix stack
2378 call g:Xsetlist([], 'f')
2379 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2380 Xexpr "File1:10:Line1"
2381 Xexpr "File2:20:Line2"
2382 Xexpr "File3:30:Line3"
2383 let last_qf = g:Xgetlist({'nr':'$'}).nr
2384 call assert_equal(3, last_qf)
2385 let qstack = []
2386 for i in range(1, last_qf)
2387 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2388 endfor
2389 call g:Xsetlist([], 'f')
2390 for i in range(len(qstack))
2391 call g:Xsetlist([], ' ', qstack[i])
2392 endfor
2393 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2394 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2395 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2396 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2397 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002398
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002399 " Swap two quickfix lists
2400 Xexpr "File1:10:Line10"
2401 Xexpr "File2:20:Line20"
2402 Xexpr "File3:30:Line30"
2403 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2404 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2405 let l1=g:Xgetlist({'nr':1,'all':1})
2406 let l2=g:Xgetlist({'nr':2,'all':1})
2407 let save_id = l1.id
2408 let l1.id=l2.id
2409 let l2.id=save_id
2410 call g:Xsetlist([], 'r', l1)
2411 call g:Xsetlist([], 'r', l2)
2412 let newl1=g:Xgetlist({'nr':1,'all':1})
2413 let newl2=g:Xgetlist({'nr':2,'all':1})
2414 call assert_equal('Fruits', newl1.title)
2415 call assert_equal(['Fruits'], newl1.context)
2416 call assert_equal('Line20', newl1.items[0].text)
2417 call assert_equal('Colors', newl2.title)
2418 call assert_equal(['Colors'], newl2.context)
2419 call assert_equal('Line10', newl2.items[0].text)
2420 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002421
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002422 " Cannot specify both a non-empty list argument and a dict argument
2423 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002424endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002425
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002426func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002427 call Xproperty_tests('c')
2428 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002429endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002430
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002431" Test for setting the current index in the location/quickfix list
2432func Xtest_setqfidx(cchar)
2433 call s:setup_commands(a:cchar)
2434
2435 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2436 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2437 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2438
2439 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2440 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2441 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2442 Xolder 2
2443 Xopen
2444 call assert_equal(3, line('.'))
2445 Xnewer
2446 call assert_equal(2, line('.'))
2447 Xnewer
2448 call assert_equal(2, line('.'))
2449 " Update the current index with the quickfix window open
2450 wincmd w
2451 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2452 Xopen
2453 call assert_equal(3, line('.'))
2454 Xclose
2455
2456 " Set the current index to the last entry
2457 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2458 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2459 " A large value should set the index to the last index
2460 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2461 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2462 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2463 " Invalid index values
2464 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2465 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2466 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2467 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2468 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2469 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2470 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2471
2472 call g:Xsetlist([], 'f')
2473 new | only
2474endfunc
2475
2476func Test_setqfidx()
2477 call Xtest_setqfidx('c')
2478 call Xtest_setqfidx('l')
2479endfunc
2480
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002481" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002482func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002483 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002484endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002485
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002486func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002487 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2488 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2489
2490 let g:acmds = []
2491 cexpr "F1:10:Line 10"
2492 caddexpr "F1:20:Line 20"
2493 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002494 cexpr ""
2495 caddexpr ""
2496 cgetexpr ""
2497 silent! cexpr non_existing_func()
2498 silent! caddexpr non_existing_func()
2499 silent! cgetexpr non_existing_func()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002500 let l = ['precexpr',
2501 \ 'postcexpr',
2502 \ 'precaddexpr',
2503 \ 'postcaddexpr',
2504 \ 'precgetexpr',
2505 \ 'postcgetexpr',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002506 \ 'precexpr',
2507 \ 'postcexpr',
2508 \ 'precaddexpr',
2509 \ 'postcaddexpr',
2510 \ 'precgetexpr',
2511 \ 'postcgetexpr',
2512 \ 'precexpr',
2513 \ 'precaddexpr',
2514 \ 'precgetexpr']
2515 call assert_equal(l, g:acmds)
2516
2517 let g:acmds = []
2518 enew! | call append(0, "F2:10:Line 10")
2519 cbuffer!
2520 enew! | call append(0, "F2:20:Line 20")
2521 cgetbuffer
2522 enew! | call append(0, "F2:30:Line 30")
2523 caddbuffer
2524 new
2525 let bnum = bufnr('%')
2526 bunload
2527 exe 'silent! cbuffer! ' . bnum
2528 exe 'silent! cgetbuffer ' . bnum
2529 exe 'silent! caddbuffer ' . bnum
2530 enew!
2531 let l = ['precbuffer',
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002532 \ 'postcbuffer',
2533 \ 'precgetbuffer',
2534 \ 'postcgetbuffer',
2535 \ 'precaddbuffer',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002536 \ 'postcaddbuffer',
2537 \ 'precbuffer',
2538 \ 'precgetbuffer',
2539 \ 'precaddbuffer']
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002540 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002541
2542 call writefile(['Xtest:1:Line1'], 'Xtest')
2543 call writefile([], 'Xempty')
2544 let g:acmds = []
2545 cfile Xtest
2546 caddfile Xtest
2547 cgetfile Xtest
2548 cfile Xempty
2549 caddfile Xempty
2550 cgetfile Xempty
2551 silent! cfile do_not_exist
2552 silent! caddfile do_not_exist
2553 silent! cgetfile do_not_exist
2554 let l = ['precfile',
2555 \ 'postcfile',
2556 \ 'precaddfile',
2557 \ 'postcaddfile',
2558 \ 'precgetfile',
2559 \ 'postcgetfile',
2560 \ 'precfile',
2561 \ 'postcfile',
2562 \ 'precaddfile',
2563 \ 'postcaddfile',
2564 \ 'precgetfile',
2565 \ 'postcgetfile',
2566 \ 'precfile',
2567 \ 'postcfile',
2568 \ 'precaddfile',
2569 \ 'postcaddfile',
2570 \ 'precgetfile',
2571 \ 'postcgetfile']
2572 call assert_equal(l, g:acmds)
2573
2574 let g:acmds = []
2575 helpgrep quickfix
2576 silent! helpgrep non_existing_help_topic
2577 vimgrep test Xtest
2578 vimgrepadd test Xtest
2579 silent! vimgrep non_existing_test Xtest
2580 silent! vimgrepadd non_existing_test Xtest
2581 set makeprg=
2582 silent! make
2583 set makeprg&
2584 let l = ['prehelpgrep',
2585 \ 'posthelpgrep',
2586 \ 'prehelpgrep',
2587 \ 'posthelpgrep',
2588 \ 'previmgrep',
2589 \ 'postvimgrep',
2590 \ 'previmgrepadd',
2591 \ 'postvimgrepadd',
2592 \ 'previmgrep',
2593 \ 'postvimgrep',
2594 \ 'previmgrepadd',
2595 \ 'postvimgrepadd',
2596 \ 'premake',
2597 \ 'postmake']
2598 call assert_equal(l, g:acmds)
2599
2600 if has('unix')
2601 " Run this test only on Unix-like systems. The grepprg may not be set on
2602 " non-Unix systems.
2603 " The following lines are used for the grep test. Don't remove.
2604 " Grep_Autocmd_Text: Match 1
2605 " GrepAdd_Autocmd_Text: Match 2
2606 let g:acmds = []
2607 silent grep Grep_Autocmd_Text test_quickfix.vim
2608 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2609 silent grep abc123def Xtest
2610 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002611 set grepprg=internal
2612 silent grep Grep_Autocmd_Text test_quickfix.vim
2613 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2614 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2615 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2616 set grepprg&vim
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002617 let l = ['pregrep',
2618 \ 'postgrep',
2619 \ 'pregrepadd',
2620 \ 'postgrepadd',
2621 \ 'pregrep',
2622 \ 'postgrep',
2623 \ 'pregrepadd',
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002624 \ 'postgrepadd',
2625 \ 'pregrep',
2626 \ 'postgrep',
2627 \ 'pregrepadd',
2628 \ 'postgrepadd',
2629 \ 'prelgrep',
2630 \ 'postlgrep',
2631 \ 'prelgrepadd',
2632 \ 'postlgrepadd']
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002633 call assert_equal(l, g:acmds)
2634 endif
2635
2636 call delete('Xtest')
2637 call delete('Xempty')
Bram Moolenaarb254af32017-12-18 19:48:58 +01002638 au! QuickFixCmdPre
2639 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002640endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002641
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002642func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002643 set efm=%m
2644 lgetexpr '?'
2645
2646 try
2647 call DoesNotExit()
2648 catch
2649 lgetexpr '1'
2650 finally
2651 lgetexpr '1'
2652 endtry
2653
2654 call assert_equal('1', getloclist(0)[0].text)
2655
2656 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002657endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002658
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002659func Test_caddbuffer_wrong()
2660 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002661 let save_efm = &efm
2662 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2663 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2664 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002665 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002666 bwipe!
2667endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002668
2669func Test_caddexpr_wrong()
2670 " This used to cause a memory access in freed memory.
2671 cbuffer
2672 cbuffer
2673 copen
2674 let save_efm = &efm
2675 set efm=%
2676 call assert_fails('caddexpr ""', 'E376:')
2677 let &efm = save_efm
2678endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01002679
2680func Test_dirstack_cleanup()
2681 " This used to cause a memory access in freed memory.
2682 let save_efm = &efm
2683 lexpr '0'
2684 lopen
2685 fun X(c)
2686 let save_efm=&efm
2687 set efm=%D%f
2688 if a:c == 'c'
2689 caddexpr '::'
2690 else
2691 laddexpr ':0:0'
2692 endif
2693 let &efm=save_efm
2694 endfun
2695 call X('c')
2696 call X('l')
2697 call setqflist([], 'r')
2698 caddbuffer
2699 let &efm = save_efm
2700endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002701
2702" Tests for jumping to entries from the location list window and quickfix
2703" window
2704func Test_cwindow_jump()
2705 set efm=%f%%%l%%%m
2706 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2707 lopen | only
2708 lfirst
2709 call assert_true(winnr('$') == 2)
2710 call assert_true(winnr() == 1)
2711 " Location list for the new window should be set
2712 call assert_true(getloclist(0)[2].text == 'Line 30')
2713
2714 " Open a scratch buffer
2715 " Open a new window and create a location list
2716 " Open the location list window and close the other window
2717 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01002718 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002719 " should not be used.
2720 enew | only
2721 set buftype=nofile
2722 below new
2723 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2724 lopen
2725 2wincmd c
2726 lnext
2727 call assert_true(winnr('$') == 3)
2728 call assert_true(winnr() == 2)
2729
2730 " Open two windows with two different location lists
2731 " Open the location list window and close the previous window
2732 " Jump to an entry in the location list window
2733 " Should open the file in the first window and not set the location list.
2734 enew | only
2735 lgetexpr ["F1%5%Line 5"]
2736 below new
2737 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2738 lopen
2739 2wincmd c
2740 lnext
2741 call assert_true(winnr() == 1)
2742 call assert_true(getloclist(0)[0].text == 'Line 5')
2743
2744 enew | only
2745 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2746 copen
2747 cnext
2748 call assert_true(winnr('$') == 2)
2749 call assert_true(winnr() == 1)
2750
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002751 " open the quickfix buffer in two windows and jump to an entry. Should open
2752 " the file in the first quickfix window.
2753 enew | only
2754 copen
2755 let bnum = bufnr('')
2756 exe 'sbuffer ' . bnum
2757 wincmd b
2758 cfirst
2759 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002760 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002761 enew | only
2762 exe 'sb' bnum
2763 exe 'botright sb' bnum
2764 wincmd t
2765 clast
2766 call assert_equal(2, winnr())
2767 call assert_equal('quickfix', getwinvar(1, '&buftype'))
2768 call assert_equal('quickfix', getwinvar(3, '&buftype'))
2769
Bram Moolenaar4b96df52020-01-26 22:00:26 +01002770 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002771 " window by wrapping around the window list.
2772 enew | only
2773 call setloclist(0, [], 'f')
2774 new | new
2775 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2776 lopen
2777 1close
2778 call assert_equal(0, getloclist(3, {'id' : 0}).id)
2779 lnext
2780 call assert_equal(3, winnr())
2781 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
2782
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002783 enew | only
2784 set efm&vim
2785endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01002786
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002787func Test_cwindow_highlight()
2788 CheckScreendump
2789
2790 let lines =<< trim END
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002791 call setline(1, ['some', 'text', 'with', 'matches'])
2792 write XCwindow
2793 vimgrep e XCwindow
2794 redraw
2795 cwindow 4
2796 END
2797 call writefile(lines, 'XtestCwindow')
2798 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
2799 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
2800
2801 call term_sendkeys(buf, ":cnext\<CR>")
2802 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
2803
2804 " clean up
2805 call StopVimInTerminal(buf)
2806 call delete('XtestCwindow')
2807 call delete('XCwindow')
2808endfunc
2809
Bram Moolenaaree85df32017-03-19 14:19:50 +01002810func XvimgrepTests(cchar)
2811 call s:setup_commands(a:cchar)
2812
2813 call writefile(['Editor:VIM vim',
2814 \ 'Editor:Emacs EmAcS',
2815 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
2816 call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2')
2817
2818 " Error cases
2819 call assert_fails('Xvimgrep /abc *', 'E682:')
2820
2821 let @/=''
2822 call assert_fails('Xvimgrep // *', 'E35:')
2823
2824 call assert_fails('Xvimgrep abc', 'E683:')
2825 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2826 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2827
2828 Xexpr ""
2829 Xvimgrepadd Notepad Xtestfile1
2830 Xvimgrepadd MacOS Xtestfile2
2831 let l = g:Xgetlist()
2832 call assert_equal(2, len(l))
2833 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2834
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002835 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01002836 let l = g:Xgetlist()
2837 call assert_equal(2, len(l))
2838 call assert_equal(8, l[0].col)
2839 call assert_equal(12, l[1].col)
2840
2841 1Xvimgrep ?Editor? Xtestfile*
2842 let l = g:Xgetlist()
2843 call assert_equal(1, len(l))
2844 call assert_equal('Editor:VIM vim', l[0].text)
2845
2846 edit +3 Xtestfile2
2847 Xvimgrep +\cemacs+j Xtestfile1
2848 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002849 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002850 call assert_equal('Editor:Emacs EmAcS', l[0].text)
2851
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02002852 " Test for unloading a buffer after vimgrep searched the buffer
2853 %bwipe
2854 Xvimgrep /Editor/j Xtestfile*
2855 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
2856 call assert_equal([], getbufinfo('Xtestfile2'))
2857
Bram Moolenaaree85df32017-03-19 14:19:50 +01002858 call delete('Xtestfile1')
2859 call delete('Xtestfile2')
2860endfunc
2861
2862" Tests for the :vimgrep command
2863func Test_vimgrep()
2864 call XvimgrepTests('c')
2865 call XvimgrepTests('l')
2866endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002867
Bram Moolenaarf8c6a172021-01-30 18:09:06 +01002868func Test_vimgrep_wildcards_expanded_once()
2869 new X[id-01] file.txt
2870 call setline(1, 'some text to search for')
2871 vimgrep text %
2872 bwipe!
2873endfunc
2874
Bram Moolenaar1c299432018-10-28 14:36:09 +01002875" Test for incsearch highlighting of the :vimgrep pattern
2876" This test used to cause "E315: ml_get: invalid lnum" errors.
2877func Test_vimgrep_incsearch()
2878 enew
2879 set incsearch
2880 call test_override("char_avail", 1)
2881
2882 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
2883 let l = getqflist()
2884 call assert_equal(2, len(l))
2885
2886 call test_override("ALL", 0)
2887 set noincsearch
2888endfunc
2889
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01002890" Test vimgrep with the last search pattern not set
2891func Test_vimgrep_with_no_last_search_pat()
2892 let lines =<< trim [SCRIPT]
2893 call assert_fails('vimgrep // *', 'E35:')
2894 call writefile(v:errors, 'Xresult')
2895 qall!
2896 [SCRIPT]
2897 call writefile(lines, 'Xscript')
2898 if RunVim([], [], '--clean -S Xscript')
2899 call assert_equal([], readfile('Xresult'))
2900 endif
2901 call delete('Xscript')
2902 call delete('Xresult')
2903endfunc
2904
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02002905" Test vimgrep without swap file
2906func Test_vimgrep_without_swap_file()
2907 let lines =<< trim [SCRIPT]
2908 vimgrep grep test_c*
2909 call writefile(['done'], 'Xresult')
2910 qall!
2911 [SCRIPT]
2912 call writefile(lines, 'Xscript')
2913 if RunVim([], [], '--clean -n -S Xscript Xscript')
2914 call assert_equal(['done'], readfile('Xresult'))
2915 endif
2916 call delete('Xscript')
2917 call delete('Xresult')
2918endfunc
2919
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002920func Test_vimgrep_existing_swapfile()
2921 call writefile(['match apple with apple'], 'Xapple')
2922 call writefile(['swapfile'], '.Xapple.swp')
2923 let g:foundSwap = 0
2924 let g:ignoreSwapExists = 1
2925 augroup grep
2926 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
2927 augroup END
2928 vimgrep apple Xapple
2929 call assert_equal(1, g:foundSwap)
2930 call assert_match('.Xapple.swo', swapname(''))
2931
2932 call delete('Xapple')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002933 call delete('.Xapple.swp')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002934 augroup grep
2935 au! SwapExists
2936 augroup END
2937 unlet g:ignoreSwapExists
2938endfunc
2939
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002940func XfreeTests(cchar)
2941 call s:setup_commands(a:cchar)
2942
2943 enew | only
2944
2945 " Deleting the quickfix stack should work even When the current list is
2946 " somewhere in the middle of the stack
2947 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2948 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2949 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2950 Xolder
2951 call g:Xsetlist([], 'f')
2952 call assert_equal(0, len(g:Xgetlist()))
2953
2954 " After deleting the stack, adding a new list should create a stack with a
2955 " single list.
2956 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2957 call assert_equal(1, g:Xgetlist({'all':1}).nr)
2958
2959 " Deleting the stack from a quickfix window should update/clear the
2960 " quickfix/location list window.
2961 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2962 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2963 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2964 Xolder
2965 Xwindow
2966 call g:Xsetlist([], 'f')
2967 call assert_equal(2, winnr('$'))
2968 call assert_equal(1, line('$'))
2969 Xclose
2970
2971 " Deleting the stack from a non-quickfix window should update/clear the
2972 " quickfix/location list window.
2973 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2974 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2975 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2976 Xolder
2977 Xwindow
2978 wincmd p
2979 call g:Xsetlist([], 'f')
2980 call assert_equal(0, len(g:Xgetlist()))
2981 wincmd p
2982 call assert_equal(2, winnr('$'))
2983 call assert_equal(1, line('$'))
2984
2985 " After deleting the location list stack, if the location list window is
2986 " opened, then a new location list should be created. So opening the
2987 " location list window again should not create a new window.
2988 if a:cchar == 'l'
2989 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2990 wincmd p
2991 lopen
2992 call assert_equal(2, winnr('$'))
2993 endif
2994 Xclose
2995endfunc
2996
Bram Moolenaar74240d32017-12-10 15:26:15 +01002997" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002998func Test_qf_free()
2999 call XfreeTests('c')
3000 call XfreeTests('l')
3001endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003002
3003" Test for buffer overflow when parsing lines and adding new entries to
3004" the quickfix list.
3005func Test_bufoverflow()
3006 set efm=%f:%l:%m
3007 cgetexpr ['File1:100:' . repeat('x', 1025)]
3008
3009 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3010 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3011
3012 set efm=%DEntering\ directory\ %f,%f:%l:%m
3013 cgetexpr ['Entering directory ' . repeat('a', 1006),
3014 \ 'File1:10:Hello World']
3015 set efm&vim
3016endfunc
3017
Bram Moolenaar875feea2017-06-11 16:07:51 +02003018" Tests for getting the quickfix stack size
3019func XsizeTests(cchar)
3020 call s:setup_commands(a:cchar)
3021
3022 call g:Xsetlist([], 'f')
3023 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003024 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3025 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003026
3027 Xexpr "File1:10:Line1"
3028 Xexpr "File2:20:Line2"
3029 Xexpr "File3:30:Line3"
3030 Xolder | Xolder
3031 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3032 call g:Xsetlist([], 'f')
3033
3034 Xexpr "File1:10:Line1"
3035 Xexpr "File2:20:Line2"
3036 Xexpr "File3:30:Line3"
3037 Xolder | Xolder
3038 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3039 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3040endfunc
3041
3042func Test_Qf_Size()
3043 call XsizeTests('c')
3044 call XsizeTests('l')
3045endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003046
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003047func Test_cclose_from_copen()
3048 augroup QF_Test
3049 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003050 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003051 augroup END
3052 copen
3053 augroup QF_Test
3054 au!
3055 augroup END
3056 augroup! QF_Test
3057endfunc
3058
Bram Moolenaar18141832017-06-25 21:17:25 +02003059func Test_cclose_in_autocmd()
3060 " Problem is only triggered if "starting" is zero, so that the OptionsSet
3061 " event will be triggered.
3062 call test_override('starting', 1)
3063 augroup QF_Test
3064 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003065 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003066 augroup END
3067 copen
3068 augroup QF_Test
3069 au!
3070 augroup END
3071 augroup! QF_Test
3072 call test_override('starting', 0)
3073endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003074
Bram Moolenaar379fb762018-08-30 15:58:28 +02003075" Check that ":file" without an argument is possible even when "curbuf_lock"
3076" is set.
3077func Test_file_from_copen()
3078 " Works without argument.
3079 augroup QF_Test
3080 au!
3081 au FileType qf file
3082 augroup END
3083 copen
3084
3085 augroup QF_Test
3086 au!
3087 augroup END
3088 cclose
3089
3090 " Fails with argument.
3091 augroup QF_Test
3092 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003093 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003094 augroup END
3095 copen
3096 augroup QF_Test
3097 au!
3098 augroup END
3099 cclose
3100
3101 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003102endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003103
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003104func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003105 augroup QF_Test
3106 au!
3107 au FileType qf resize 5
3108 augroup END
3109 try
3110 " This should succeed without any exception. No other buffers are
3111 " involved in the autocmd.
3112 copen
3113 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003114 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003115 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003116 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003117 augroup! QF_Test
3118 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003119endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003120
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003121func Test_vimgrep_with_textlock()
3122 new
3123
3124 " Simple way to execute something with "textwinlock" set.
3125 " Check that vimgrep without jumping can be executed.
3126 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3127 normal ax
3128 let qflist = getqflist()
3129 call assert_true(len(qflist) > 0)
3130 call assert_match('RunTheTest', qflist[0].text)
3131 call setqflist([], 'r')
3132 au! InsertCharPre
3133
3134 " Check that vimgrepadd without jumping can be executed.
3135 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3136 normal ax
3137 let qflist = getqflist()
3138 call assert_true(len(qflist) > 0)
3139 call assert_match('RunTheTest', qflist[0].text)
3140 call setqflist([], 'r')
3141 au! InsertCharPre
3142
3143 " Check that lvimgrep without jumping can be executed.
3144 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3145 normal ax
3146 let qflist = getloclist(0)
3147 call assert_true(len(qflist) > 0)
3148 call assert_match('RunTheTest', qflist[0].text)
3149 call setloclist(0, [], 'r')
3150 au! InsertCharPre
3151
3152 " Check that lvimgrepadd without jumping can be executed.
3153 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3154 normal ax
3155 let qflist = getloclist(0)
3156 call assert_true(len(qflist) > 0)
3157 call assert_match('RunTheTest', qflist[0].text)
3158 call setloclist(0, [], 'r')
3159 au! InsertCharPre
3160
3161 " trying to jump will give an error
3162 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3163 call assert_fails('normal ax', 'E565:')
3164 au! InsertCharPre
3165
3166 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3167 call assert_fails('normal ax', 'E565:')
3168 au! InsertCharPre
3169
3170 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3171 call assert_fails('normal ax', 'E565:')
3172 au! InsertCharPre
3173
3174 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3175 call assert_fails('normal ax', 'E565:')
3176 au! InsertCharPre
3177
3178 bwipe!
3179endfunc
3180
Bram Moolenaara8788f42017-07-19 17:06:20 +02003181" Tests for the quickfix buffer b:changedtick variable
3182func Xchangedtick_tests(cchar)
3183 call s:setup_commands(a:cchar)
3184
3185 new | only
3186
3187 Xexpr "" | Xexpr "" | Xexpr ""
3188
3189 Xopen
3190 Xolder
3191 Xolder
3192 Xaddexpr "F1:10:Line10"
3193 Xaddexpr "F2:20:Line20"
3194 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3195 call g:Xsetlist([], 'f')
3196 call assert_equal(8, getbufvar('%', 'changedtick'))
3197 Xclose
3198endfunc
3199
3200func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003201 call Xchangedtick_tests('c')
3202 call Xchangedtick_tests('l')
3203endfunc
3204
3205" Tests for parsing an expression using setqflist()
3206func Xsetexpr_tests(cchar)
3207 call s:setup_commands(a:cchar)
3208
3209 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003210 call g:Xsetlist([], ' ', {'lines' : t})
3211 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003212
3213 let l = g:Xgetlist()
3214 call assert_equal(3, len(l))
3215 call assert_equal(20, l[1].lnum)
3216 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003217 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003218 let l = g:Xgetlist()
3219 call assert_equal(1, len(l))
3220 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003221 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3222 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003223
3224 call g:Xsetlist([], 'f')
3225 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003226 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3227 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3228 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3229 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003230 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3231 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003232
3233 " Adding entries using a custom efm
3234 set efm&
3235 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3236 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3237 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3238 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3239 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3240 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3241 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3242 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003243endfunc
3244
3245func Test_setexpr()
3246 call Xsetexpr_tests('c')
3247 call Xsetexpr_tests('l')
3248endfunc
3249
3250" Tests for per quickfix/location list directory stack
3251func Xmultidirstack_tests(cchar)
3252 call s:setup_commands(a:cchar)
3253
3254 call g:Xsetlist([], 'f')
3255 Xexpr "" | Xexpr ""
3256
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003257 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3258 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3259 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3260 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003261
3262 let l1 = g:Xgetlist({'nr':1, 'items':1})
3263 let l2 = g:Xgetlist({'nr':2, 'items':1})
3264 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3265 call assert_equal(3, l1.items[1].lnum)
3266 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3267 call assert_equal(5, l2.items[1].lnum)
3268endfunc
3269
3270func Test_multidirstack()
3271 call mkdir('Xone/a', 'p')
3272 call mkdir('Xtwo/a', 'p')
3273 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3274 call writefile(lines, 'Xone/a/one.txt')
3275 call writefile(lines, 'Xtwo/a/two.txt')
3276 let save_efm = &efm
3277 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3278
3279 call Xmultidirstack_tests('c')
3280 call Xmultidirstack_tests('l')
3281
3282 let &efm = save_efm
3283 call delete('Xone', 'rf')
3284 call delete('Xtwo', 'rf')
3285endfunc
3286
3287" Tests for per quickfix/location list file stack
3288func Xmultifilestack_tests(cchar)
3289 call s:setup_commands(a:cchar)
3290
3291 call g:Xsetlist([], 'f')
3292 Xexpr "" | Xexpr ""
3293
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003294 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3295 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3296 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3297 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003298
3299 let l1 = g:Xgetlist({'nr':1, 'items':1})
3300 let l2 = g:Xgetlist({'nr':2, 'items':1})
3301 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3302 call assert_equal(3, l1.items[1].lnum)
3303 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3304 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003305
3306 " Test for start of a new error line in the same line where a previous
3307 " error line ends with a file stack.
3308 let efm_val = 'Error\ l%l\ in\ %f,'
3309 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
3310 let l = g:Xgetlist({'lines' : [
3311 \ '(one.txt',
3312 \ 'Error l4 in one.txt',
3313 \ ') (two.txt',
3314 \ 'Error l6 in two.txt',
3315 \ ')',
3316 \ 'Error l8 in one.txt'
3317 \ ], 'efm' : efm_val})
3318 call assert_equal(3, len(l.items))
3319 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3320 call assert_equal(4, l.items[0].lnum)
3321 call assert_equal('one.txt', l.items[0].text)
3322 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3323 call assert_equal(6, l.items[1].lnum)
3324 call assert_equal('two.txt', l.items[1].text)
3325 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3326 call assert_equal(8, l.items[2].lnum)
3327 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003328endfunc
3329
3330func Test_multifilestack()
3331 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3332 call writefile(lines, 'one.txt')
3333 call writefile(lines, 'two.txt')
3334 let save_efm = &efm
3335 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3336
3337 call Xmultifilestack_tests('c')
3338 call Xmultifilestack_tests('l')
3339
3340 let &efm = save_efm
3341 call delete('one.txt')
3342 call delete('two.txt')
3343endfunc
3344
3345" Tests for per buffer 'efm' setting
3346func Test_perbuf_efm()
3347 call writefile(["File1-10-Line10"], 'one.txt')
3348 call writefile(["File2#20#Line20"], 'two.txt')
3349 set efm=%f#%l#%m
3350 new | only
3351 new
3352 setlocal efm=%f-%l-%m
3353 cfile one.txt
3354 wincmd w
3355 caddfile two.txt
3356
3357 let l = getqflist()
3358 call assert_equal(10, l[0].lnum)
3359 call assert_equal('Line20', l[1].text)
3360
3361 set efm&
3362 new | only
3363 call delete('one.txt')
3364 call delete('two.txt')
Bram Moolenaara8788f42017-07-19 17:06:20 +02003365endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003366
3367" Open multiple help windows using ":lhelpgrep
3368" This test used to crash Vim
3369func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003370 new | only
3371 lhelpgrep window
3372 lopen
3373 e#
3374 lhelpgrep buffer
3375 call assert_equal(3, winnr('$'))
3376 call assert_true(len(getloclist(1)) != 0)
3377 call assert_true(len(getloclist(2)) != 0)
3378 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003379endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003380
3381" Tests for adding new quickfix lists using setqflist()
3382func XaddQf_tests(cchar)
3383 call s:setup_commands(a:cchar)
3384
3385 " Create a new list using ' ' for action
3386 call g:Xsetlist([], 'f')
3387 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3388 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3389 call assert_equal(1, l.nr)
3390 call assert_equal('Test1', l.title)
3391
3392 " Create a new list using ' ' for action and '$' for 'nr'
3393 call g:Xsetlist([], 'f')
3394 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3395 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3396 call assert_equal(1, l.nr)
3397 call assert_equal('Test2', l.title)
3398
3399 " Create a new list using 'a' for action
3400 call g:Xsetlist([], 'f')
3401 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3402 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3403 call assert_equal(1, l.nr)
3404 call assert_equal('Test3', l.title)
3405
3406 " Create a new list using 'a' for action and '$' for 'nr'
3407 call g:Xsetlist([], 'f')
3408 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3409 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3410 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3411 call assert_equal(1, l.nr)
3412 call assert_equal('Test4', l.title)
3413
3414 " Adding a quickfix list should remove all the lists following the current
3415 " list.
3416 Xexpr "" | Xexpr "" | Xexpr ""
3417 silent! 10Xolder
3418 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3419 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3420 call assert_equal(2, l.nr)
3421 call assert_equal('Test5', l.title)
3422
3423 " Add a quickfix list using '$' as the list number.
3424 let lastqf = g:Xgetlist({'nr':'$'}).nr
3425 silent! 99Xolder
3426 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3427 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3428 call assert_equal(lastqf + 1, l.nr)
3429 call assert_equal('Test6', l.title)
3430
3431 " Add a quickfix list using 'nr' set to one more than the quickfix
3432 " list size.
3433 let lastqf = g:Xgetlist({'nr':'$'}).nr
3434 silent! 99Xolder
3435 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3436 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3437 call assert_equal(lastqf + 1, l.nr)
3438 call assert_equal('Test7', l.title)
3439
3440 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3441 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3442 silent! 99Xolder
3443 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3444 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3445 call assert_equal(10, l.nr)
3446 call assert_equal('Test8', l.title)
3447
3448 " Add a quickfix list using 'nr' set to a value greater than 10
3449 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3450
3451 " Try adding a quickfix list with 'nr' set to a value greater than the
3452 " quickfix list size but less than 10.
3453 call g:Xsetlist([], 'f')
3454 Xexpr "" | Xexpr "" | Xexpr ""
3455 silent! 99Xolder
3456 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3457
3458 " Add a quickfix list using 'nr' set to a some string or list
3459 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3460endfunc
3461
3462func Test_add_qf()
3463 call XaddQf_tests('c')
3464 call XaddQf_tests('l')
3465endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003466
3467" Test for getting the quickfix list items from some text without modifying
3468" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003469func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003470 call s:setup_commands(a:cchar)
3471 call g:Xsetlist([], 'f')
3472
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003473 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003474 call assert_equal(2, len(l))
3475 call assert_equal(30, l[1].lnum)
3476
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003477 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3478 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3479 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3480 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003481
Bram Moolenaar36538222017-09-02 19:51:44 +02003482 " Parse text using a custom efm
3483 set efm&
3484 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3485 call assert_equal('Line30', l[0].text)
3486 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3487 call assert_equal('File3:30:Line30', l[0].text)
3488 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3489 call assert_equal({}, l)
3490 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3491 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3492
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003493 " Make sure that the quickfix stack is not modified
3494 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3495endfunc
3496
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003497func Test_get_list_from_lines()
3498 call XgetListFromLines('c')
3499 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003500endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003501
3502" Tests for the quickfix list id
3503func Xqfid_tests(cchar)
3504 call s:setup_commands(a:cchar)
3505
3506 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003507 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003508 Xexpr ''
3509 let start_id = g:Xgetlist({'id' : 0}).id
3510 Xexpr '' | Xexpr ''
3511 Xolder
3512 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3513 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3514 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003515 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003516 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003517 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3518 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003519
3520 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3521 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003522 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003523 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3524 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3525 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3526
3527 let qfid = g:Xgetlist({'id':0, 'nr':0})
3528 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003529 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003530endfunc
3531
3532func Test_qf_id()
3533 call Xqfid_tests('c')
3534 call Xqfid_tests('l')
3535endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003536
3537func Xqfjump_tests(cchar)
3538 call s:setup_commands(a:cchar)
3539
3540 call writefile(["Line1\tFoo", "Line2"], 'F1')
3541 call writefile(["Line1\tBar", "Line2"], 'F2')
3542 call writefile(["Line1\tBaz", "Line2"], 'F3')
3543
3544 call g:Xsetlist([], 'f')
3545
3546 " Tests for
3547 " Jumping to a line using a pattern
3548 " Jumping to a column greater than the last column in a line
3549 " Jumping to a line greater than the last line in the file
3550 let l = []
3551 for i in range(1, 7)
3552 call add(l, {})
3553 endfor
3554 let l[0].filename='F1'
3555 let l[0].pattern='Line1'
3556 let l[1].filename='F2'
3557 let l[1].pattern='Line1'
3558 let l[2].filename='F3'
3559 let l[2].pattern='Line1'
3560 let l[3].filename='F3'
3561 let l[3].lnum=1
3562 let l[3].col=9
3563 let l[3].vcol=1
3564 let l[4].filename='F3'
3565 let l[4].lnum=99
3566 let l[5].filename='F3'
3567 let l[5].lnum=1
3568 let l[5].col=99
3569 let l[5].vcol=1
3570 let l[6].filename='F3'
3571 let l[6].pattern='abcxyz'
3572
3573 call g:Xsetlist([], ' ', {'items' : l})
3574 Xopen | only
3575 2Xnext
3576 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003577 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003578 Xnext
3579 call assert_equal(7, col('.'))
3580 Xnext
3581 call assert_equal(2, line('.'))
3582 Xnext
3583 call assert_equal(9, col('.'))
3584 2
3585 Xnext
3586 call assert_equal(2, line('.'))
3587
3588 if a:cchar == 'l'
3589 " When jumping to a location list entry in the location list window and
3590 " no usable windows are available, then a new window should be opened.
3591 enew! | new | only
3592 call g:Xsetlist([], 'f')
3593 setlocal buftype=nofile
3594 new
3595 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']})
3596 Xopen
3597 let winid = win_getid()
3598 wincmd p
3599 close
3600 call win_gotoid(winid)
3601 Xnext
3602 call assert_equal(3, winnr('$'))
3603 call assert_equal(1, winnr())
3604 call assert_equal(2, line('.'))
3605
3606 " When jumping to an entry in the location list window and the window
3607 " associated with the location list is not present and a window containing
3608 " the file is already present, then that window should be used.
3609 close
3610 belowright new
3611 call g:Xsetlist([], 'f')
3612 edit F3
3613 call win_gotoid(winid)
3614 Xlast
3615 call assert_equal(3, winnr())
3616 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3617 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3618 endif
3619
3620 " Cleanup
3621 enew!
3622 new | only
3623
3624 call delete('F1')
3625 call delete('F2')
3626 call delete('F3')
3627endfunc
3628
3629func Test_qfjump()
3630 call Xqfjump_tests('c')
3631 call Xqfjump_tests('l')
3632endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003633
3634" Tests for the getqflist() and getloclist() functions when the list is not
3635" present or is empty
3636func Xgetlist_empty_tests(cchar)
3637 call s:setup_commands(a:cchar)
3638
3639 " Empty quickfix stack
3640 call g:Xsetlist([], 'f')
3641 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3642 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3643 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3644 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3645 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3646 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3647 call assert_equal('', g:Xgetlist({'title' : 0}).title)
3648 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003649 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003650 if a:cchar == 'c'
3651 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003652 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003653 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
3654 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003655 else
3656 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3657 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003658 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003659 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003660 \ g:Xgetlist({'all' : 0}))
3661 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003662
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003663 " Quickfix window with empty stack
3664 silent! Xopen
3665 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003666 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003667 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3668 Xclose
3669
Bram Moolenaara6d48492017-12-12 22:45:31 +01003670 " Empty quickfix list
3671 Xexpr ""
3672 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3673 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3674 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3675 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3676 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3677 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3678 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3679 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003680 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003681
3682 let qfid = g:Xgetlist({'id' : 0}).id
3683 call g:Xsetlist([], 'f')
3684
3685 " Non-existing quickfix identifier
3686 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3687 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3688 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3689 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3690 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3691 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3692 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3693 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003694 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003695 if a:cchar == 'c'
3696 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3697 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003698 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003699 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3700 else
3701 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3702 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003703 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3704 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003705 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
3706 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003707
3708 " Non-existing quickfix list number
3709 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3710 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3711 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3712 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3713 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3714 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3715 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3716 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003717 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003718 if a:cchar == 'c'
3719 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3720 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003721 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
3722 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003723 else
3724 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3725 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003726 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3727 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003728 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003729endfunc
3730
3731func Test_getqflist()
3732 call Xgetlist_empty_tests('c')
3733 call Xgetlist_empty_tests('l')
3734endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01003735
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01003736func Test_getqflist_invalid_nr()
3737 " The following commands used to crash Vim
3738 cexpr ""
3739 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3740
3741 " Cleanup
3742 call setqflist([], 'r')
3743endfunc
3744
Bram Moolenaarb254af32017-12-18 19:48:58 +01003745" Tests for the quickfix/location list changedtick
3746func Xqftick_tests(cchar)
3747 call s:setup_commands(a:cchar)
3748
3749 call g:Xsetlist([], 'f')
3750
3751 Xexpr "F1:10:Line10"
3752 let qfid = g:Xgetlist({'id' : 0}).id
3753 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3754 Xaddexpr "F2:20:Line20\nF2:21:Line21"
3755 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3756 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3757 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3758 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3759 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3760 call g:Xsetlist([], 'a', {'title' : 'New Title'})
3761 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3762
3763 enew!
3764 call append(0, ["F5:50:L50", "F6:60:L60"])
3765 Xaddbuffer
3766 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3767 enew!
3768
3769 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3770 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3771 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3772 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3773 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3774 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3775 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3776 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3777 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3778 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3779 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3780
3781 call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3782 Xfile Xone
3783 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3784 Xaddfile Xone
3785 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3786
3787 " Test case for updating a non-current quickfix list
3788 call g:Xsetlist([], 'f')
3789 Xexpr "F1:1:L1"
3790 Xexpr "F2:2:L2"
3791 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3792 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3793 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3794
3795 call delete("Xone")
3796endfunc
3797
3798func Test_qf_tick()
3799 call Xqftick_tests('c')
3800 call Xqftick_tests('l')
3801endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01003802
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02003803" Test helpgrep with lang specifier
3804func Xtest_helpgrep_with_lang_specifier(cchar)
3805 call s:setup_commands(a:cchar)
3806 Xhelpgrep Vim@en
3807 call assert_equal('help', &filetype)
3808 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3809 new | only
3810endfunc
3811
3812func Test_helpgrep_with_lang_specifier()
3813 call Xtest_helpgrep_with_lang_specifier('c')
3814 call Xtest_helpgrep_with_lang_specifier('l')
3815endfunc
3816
Bram Moolenaar12237442017-12-19 12:38:52 +01003817" The following test used to crash Vim.
3818" Open the location list window and close the regular window associated with
3819" the location list. When the garbage collection runs now, it incorrectly
3820" marks the location list context as not in use and frees the context.
3821func Test_ll_window_ctx()
3822 call setloclist(0, [], 'f')
3823 call setloclist(0, [], 'a', {'context' : []})
3824 lopen | only
3825 call test_garbagecollect_now()
3826 echo getloclist(0, {'context' : 1}).context
3827 enew | only
3828endfunc
3829
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003830" The following test used to crash vim
3831func Test_lfile_crash()
3832 sp Xtest
3833 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02003834 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003835 au! QuickFixCmdPre
3836endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01003837
3838" The following test used to crash vim
3839func Test_lbuffer_crash()
3840 sv Xtest
3841 augroup QF_Test
3842 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003843 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01003844 augroup END
3845 lbuffer
3846 augroup QF_Test
3847 au!
3848 augroup END
3849endfunc
3850
3851" The following test used to crash vim
3852func Test_lexpr_crash()
3853 augroup QF_Test
3854 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003855 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003856 augroup END
3857 lexpr ""
3858 augroup QF_Test
3859 au!
3860 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003861
Bram Moolenaar3c097222017-12-21 20:54:49 +01003862 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003863 augroup QF_Test
3864 au!
3865 au BufNew * call setloclist(0, [], 'f')
3866 augroup END
3867 lexpr 'x:1:x'
3868 augroup QF_Test
3869 au!
3870 augroup END
3871
3872 enew | only
3873 lexpr ''
3874 lopen
3875 augroup QF_Test
3876 au!
3877 au FileType * call setloclist(0, [], 'f')
3878 augroup END
3879 lexpr ''
3880 augroup QF_Test
3881 au!
3882 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01003883endfunc
3884
3885" The following test used to crash Vim
3886func Test_lvimgrep_crash()
3887 sv Xtest
3888 augroup QF_Test
3889 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003890 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003891 augroup END
3892 lvimgrep quickfix test_quickfix.vim
3893 augroup QF_Test
3894 au!
3895 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003896
3897 new | only
3898 augroup QF_Test
3899 au!
3900 au BufEnter * call setloclist(0, [], 'r')
3901 augroup END
3902 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
3903 augroup QF_Test
3904 au!
3905 augroup END
3906
Bram Moolenaar3c097222017-12-21 20:54:49 +01003907 enew | only
3908endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01003909
Bram Moolenaar2573af32020-03-14 17:21:34 +01003910func Test_lvimgrep_crash2()
3911 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02003912 call assert_fails('lvimgrep x x', 'E471:')
3913 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01003914
3915 au! BufNewFile
3916endfunc
3917
Bram Moolenaarde046542017-12-26 13:53:11 +01003918" Test for the position of the quickfix and location list window
3919func Test_qfwin_pos()
3920 " Open two windows
3921 new | only
3922 new
3923 cexpr ['F1:10:L10']
3924 copen
3925 " Quickfix window should be the bottom most window
3926 call assert_equal(3, winnr())
3927 close
3928 " Open at the very top
3929 wincmd t
3930 topleft copen
3931 call assert_equal(1, winnr())
3932 close
3933 " open left of the current window
3934 wincmd t
3935 below new
3936 leftabove copen
3937 call assert_equal(2, winnr())
3938 close
3939 " open right of the current window
3940 rightbelow copen
3941 call assert_equal(3, winnr())
3942 close
3943endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02003944
3945" Tests for quickfix/location lists changed by autocommands when
3946" :vimgrep/:lvimgrep commands are running.
3947func Test_vimgrep_autocmd()
3948 call setqflist([], 'f')
3949 call writefile(['stars'], 'Xtest1.txt')
3950 call writefile(['stars'], 'Xtest2.txt')
3951
3952 " Test 1:
3953 " When searching for a pattern using :vimgrep, if the quickfix list is
3954 " changed by an autocmd, the results should be added to the correct quickfix
3955 " list.
3956 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
3957 silent vimgrep stars Xtest*.txt
3958 call assert_equal(1, getqflist({'nr' : 0}).nr)
3959 call assert_equal(3, getqflist({'nr' : '$'}).nr)
3960 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
3961 au! BufRead Xtest2.txt
3962
3963 " Test 2:
3964 " When searching for a pattern using :vimgrep, if the quickfix list is
3965 " freed, then a error should be given.
3966 silent! %bwipe!
3967 call setqflist([], 'f')
3968 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
3969 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
3970 au! BufRead Xtest2.txt
3971
3972 " Test 3:
3973 " When searching for a pattern using :lvimgrep, if the location list is
3974 " freed, then the command should error out.
3975 silent! %bwipe!
3976 let g:save_winid = win_getid()
3977 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
3978 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
3979 au! BufRead Xtest2.txt
3980
3981 call delete('Xtest1.txt')
3982 call delete('Xtest2.txt')
3983 call setqflist([], 'f')
3984endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02003985
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003986" Test for an autocmd changing the current directory when running vimgrep
3987func Xvimgrep_autocmd_cd(cchar)
3988 call s:setup_commands(a:cchar)
3989
3990 %bwipe
3991 let save_cwd = getcwd()
3992
3993 augroup QF_Test
3994 au!
3995 autocmd BufRead * silent cd %:p:h
3996 augroup END
3997
3998 10Xvimgrep /vim/ Xdir/**
3999 let l = g:Xgetlist()
4000 call assert_equal('f1.txt', bufname(l[0].bufnr))
4001 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4002
4003 augroup QF_Test
4004 au!
4005 augroup END
4006
4007 exe 'cd ' . save_cwd
4008endfunc
4009
4010func Test_vimgrep_autocmd_cd()
4011 call mkdir('Xdir/a', 'p')
4012 call mkdir('Xdir/b', 'p')
4013 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt')
4014 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt')
4015 call Xvimgrep_autocmd_cd('c')
4016 call Xvimgrep_autocmd_cd('l')
4017 %bwipe
4018 call delete('Xdir', 'rf')
4019endfunc
4020
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004021" The following test used to crash Vim
4022func Test_lhelpgrep_autocmd()
4023 lhelpgrep quickfix
4024 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4025 lhelpgrep buffer
4026 call assert_equal('help', &filetype)
4027 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4028 lhelpgrep tabpage
4029 call assert_equal('help', &filetype)
4030 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
4031 au! QuickFixCmdPost
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004032
4033 new | only
4034 augroup QF_Test
4035 au!
4036 au BufEnter * call setqflist([], 'f')
4037 augroup END
4038 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004039 " run the test with a help window already open
4040 help
4041 wincmd w
4042 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004043 augroup QF_Test
4044 au! BufEnter
4045 augroup END
4046
4047 new | only
4048 augroup QF_Test
4049 au!
4050 au BufEnter * call setqflist([], 'r')
4051 augroup END
4052 call assert_fails('helpgrep quickfix', 'E925:')
4053 augroup QF_Test
4054 au! BufEnter
4055 augroup END
4056
4057 new | only
4058 augroup QF_Test
4059 au!
4060 au BufEnter * call setloclist(0, [], 'r')
4061 augroup END
4062 call assert_fails('lhelpgrep quickfix', 'E926:')
4063 augroup QF_Test
4064 au! BufEnter
4065 augroup END
4066
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004067 new | only
4068endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004069
4070" Test for shortening/simplifying the file name when opening the
4071" quickfix window or when displaying the quickfix list
4072func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004073 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004074 %bwipe
4075 " Create a quickfix list with a absolute path filename
4076 let fname = getcwd() . '/test_quickfix.vim'
4077 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4078 call assert_equal(fname, bufname('test_quickfix.vim'))
4079 " Opening the quickfix window should simplify the file path
4080 cwindow
4081 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4082 cclose
4083 %bwipe
4084 " Create a quickfix list with a absolute path filename
4085 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4086 call assert_equal(fname, bufname('test_quickfix.vim'))
4087 " Displaying the quickfix list should simplify the file path
4088 silent! clist
4089 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004090 " Add a few entries for the same file with different paths and check whether
4091 " the buffer name is shortened
4092 %bwipe
4093 call setqflist([], 'f')
4094 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4095 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4096 \ {'filename' : fname, 'lnum' : 30}], ' ')
4097 copen
4098 call assert_equal(['test_quickfix.vim|10| ',
4099 \ 'test_quickfix.vim|20| ',
4100 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4101 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004102endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004103
4104" Quickfix title tests
4105" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4106" Otherwise due to indentation, the title is set with spaces at the beginning
4107" of the command.
4108func Test_qftitle()
4109 call writefile(["F1:1:Line1"], 'Xerr')
4110
4111 " :cexpr
4112 exe "cexpr readfile('Xerr')"
4113 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4114
4115 " :cgetexpr
4116 exe "cgetexpr readfile('Xerr')"
4117 call assert_equal(":cgetexpr readfile('Xerr')",
4118 \ getqflist({'title' : 1}).title)
4119
4120 " :caddexpr
4121 call setqflist([], 'f')
4122 exe "caddexpr readfile('Xerr')"
4123 call assert_equal(":caddexpr readfile('Xerr')",
4124 \ getqflist({'title' : 1}).title)
4125
4126 " :cbuffer
4127 new Xerr
4128 exe "cbuffer"
4129 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4130
4131 " :cgetbuffer
4132 edit Xerr
4133 exe "cgetbuffer"
4134 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4135
4136 " :caddbuffer
4137 call setqflist([], 'f')
4138 edit Xerr
4139 exe "caddbuffer"
4140 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4141
4142 " :cfile
4143 exe "cfile Xerr"
4144 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4145
4146 " :cgetfile
4147 exe "cgetfile Xerr"
4148 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4149
4150 " :caddfile
4151 call setqflist([], 'f')
4152 exe "caddfile Xerr"
4153 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4154
4155 " :grep
4156 set grepprg=internal
4157 exe "grep F1 Xerr"
4158 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4159
4160 " :grepadd
4161 call setqflist([], 'f')
4162 exe "grepadd F1 Xerr"
4163 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4164 set grepprg&vim
4165
4166 " :vimgrep
4167 exe "vimgrep F1 Xerr"
4168 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4169
4170 " :vimgrepadd
4171 call setqflist([], 'f')
4172 exe "vimgrepadd F1 Xerr"
4173 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4174
4175 call setqflist(['F1:10:L10'], ' ')
4176 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4177
4178 call setqflist([], 'f')
4179 call setqflist(['F1:10:L10'], 'a')
4180 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4181
4182 call setqflist([], 'f')
4183 call setqflist(['F1:10:L10'], 'r')
4184 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4185
4186 close
4187 call delete('Xerr')
4188
4189 call setqflist([], ' ', {'title' : 'Errors'})
4190 copen
4191 call assert_equal('Errors', w:quickfix_title)
4192 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4193 call assert_equal('Errors', w:quickfix_title)
4194 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004195
4196 " Switching to another quickfix list in one tab page should update the
4197 " quickfix window title and statusline in all the other tab pages also
4198 call setqflist([], 'f')
4199 %bw!
4200 cgetexpr ['file_one:1:1: error in the first quickfix list']
4201 call setqflist([], 'a', {'title': 'first quickfix list'})
4202 cgetexpr ['file_two:2:1: error in the second quickfix list']
4203 call setqflist([], 'a', {'title': 'second quickfix list'})
4204 copen
4205 wincmd t
4206 tabnew two
4207 copen
4208 wincmd t
4209 colder
4210 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4211 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4212 call assert_equal(1, tabpagewinnr(1))
4213 call assert_equal(1, tabpagewinnr(2))
4214 tabnew
4215 call setqflist([], 'a', {'title': 'new quickfix title'})
4216 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4217 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4218 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004219endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004220
4221func Test_lbuffer_with_bwipe()
4222 new
4223 new
4224 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004225 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004226 augroup END
4227 lbuffer
4228 augroup nasty
4229 au!
4230 augroup END
4231endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004232
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004233" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4234" running
4235func Xexpr_acmd_freelist(cchar)
4236 call s:setup_commands(a:cchar)
4237
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004238 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004239 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004240 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004241 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004242 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004243 augroup nasty
4244 au!
4245 augroup END
4246endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004247
4248func Test_cexpr_acmd_freelist()
4249 call Xexpr_acmd_freelist('c')
4250 call Xexpr_acmd_freelist('l')
4251endfunc
4252
4253" Test for commands that create a new quickfix/location list and jump to the
4254" first error automatically.
4255func Xjumpto_first_error_test(cchar)
4256 call s:setup_commands(a:cchar)
4257
4258 call s:create_test_file('Xtestfile1')
4259 call s:create_test_file('Xtestfile2')
4260 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4261
4262 " Test for cexpr/lexpr
4263 enew
4264 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004265 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004266 call assert_equal(2, line('.'))
4267
4268 " Test for cfile/lfile
4269 enew
4270 call writefile(l, 'Xerr')
4271 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004272 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004273 call assert_equal(2, line('.'))
4274
4275 " Test for cbuffer/lbuffer
4276 edit Xerr
4277 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004278 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004279 call assert_equal(2, line('.'))
4280
4281 call delete('Xerr')
4282 call delete('Xtestfile1')
4283 call delete('Xtestfile2')
4284endfunc
4285
4286func Test_jumpto_first_error()
4287 call Xjumpto_first_error_test('c')
4288 call Xjumpto_first_error_test('l')
4289endfunc
4290
4291" Test for a quickfix autocmd changing the quickfix/location list before
4292" jumping to the first error in the new list.
4293func Xautocmd_changelist(cchar)
4294 call s:setup_commands(a:cchar)
4295
4296 " Test for cfile/lfile
4297 call s:create_test_file('Xtestfile1')
4298 call s:create_test_file('Xtestfile2')
4299 Xexpr 'Xtestfile1:2:Line2'
4300 autocmd QuickFixCmdPost * Xolder
4301 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4302 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004303 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004304 call assert_equal(4, line('.'))
4305 autocmd! QuickFixCmdPost
4306
4307 " Test for cbuffer/lbuffer
4308 call g:Xsetlist([], 'f')
4309 Xexpr 'Xtestfile1:2:Line2'
4310 autocmd QuickFixCmdPost * Xolder
4311 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4312 edit Xerr
4313 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004314 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004315 call assert_equal(4, line('.'))
4316 autocmd! QuickFixCmdPost
4317
4318 " Test for cexpr/lexpr
4319 call g:Xsetlist([], 'f')
4320 Xexpr 'Xtestfile1:2:Line2'
4321 autocmd QuickFixCmdPost * Xolder
4322 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004323 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004324 call assert_equal(4, line('.'))
4325 autocmd! QuickFixCmdPost
4326
Bram Moolenaar851332e2018-07-03 19:16:00 +02004327 " The grepprg may not be set on non-Unix systems
4328 if has('unix')
4329 " Test for grep/lgrep
4330 call g:Xsetlist([], 'f')
4331 Xexpr 'Xtestfile1:2:Line2'
4332 autocmd QuickFixCmdPost * Xolder
4333 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004334 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004335 call assert_equal(5, line('.'))
4336 autocmd! QuickFixCmdPost
4337 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004338
4339 " Test for vimgrep/lvimgrep
4340 call g:Xsetlist([], 'f')
4341 Xexpr 'Xtestfile1:2:Line2'
4342 autocmd QuickFixCmdPost * Xolder
4343 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004344 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004345 call assert_equal(5, line('.'))
4346 autocmd! QuickFixCmdPost
4347
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004348 " Test for autocommands clearing the quickfix list before jumping to the
4349 " first error. This should not result in an error
4350 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4351 let v:errmsg = ''
4352 " Test for cfile/lfile
4353 Xfile Xerr
4354 call assert_true(v:errmsg !~# 'E42:')
4355 " Test for cbuffer/lbuffer
4356 edit Xerr
4357 Xbuffer
4358 call assert_true(v:errmsg !~# 'E42:')
4359 " Test for cexpr/lexpr
4360 Xexpr 'Xtestfile2:4:Line4'
4361 call assert_true(v:errmsg !~# 'E42:')
4362 " Test for grep/lgrep
4363 " The grepprg may not be set on non-Unix systems
4364 if has('unix')
4365 silent Xgrep Line5 Xtestfile2
4366 call assert_true(v:errmsg !~# 'E42:')
4367 endif
4368 " Test for vimgrep/lvimgrep
4369 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4370 autocmd! QuickFixCmdPost
4371
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004372 call delete('Xerr')
4373 call delete('Xtestfile1')
4374 call delete('Xtestfile2')
4375endfunc
4376
4377func Test_autocmd_changelist()
4378 call Xautocmd_changelist('c')
4379 call Xautocmd_changelist('l')
4380endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004381
4382" Tests for the ':filter /pat/ clist' command
4383func Test_filter_clist()
4384 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4385 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4386 \ split(execute('filter /Line 15/ clist'), "\n"))
4387 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4388 \ split(execute('filter /Xfile1/ clist'), "\n"))
4389 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4390
4391 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4392 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4393 call assert_equal([' 2 pqr:pat2: '],
4394 \ split(execute('filter /pqr/ clist'), "\n"))
4395 call assert_equal([' 1 abc:pat1: '],
4396 \ split(execute('filter /pat1/ clist'), "\n"))
4397endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004398
4399" Tests for the "CTRL-W <CR>" command.
4400func Xview_result_split_tests(cchar)
4401 call s:setup_commands(a:cchar)
4402
4403 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4404 call g:Xsetlist([])
4405 Xopen
4406 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004407 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004408 call assert_equal(l:win_count, winnr('$'))
4409 Xclose
4410endfunc
4411
4412func Test_view_result_split()
4413 call Xview_result_split_tests('c')
4414 call Xview_result_split_tests('l')
4415endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004416
4417" Test that :cc sets curswant
4418func Test_curswant()
4419 helpgrep quickfix
4420 normal! llll
4421 1cc
4422 call assert_equal(getcurpos()[4], virtcol('.'))
4423 cclose | helpclose
4424endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004425
4426" Test for opening a file from the quickfix window using CTRL-W <Enter>
4427" doesn't leave an empty buffer around.
4428func Test_splitview()
4429 call s:create_test_file('Xtestfile1')
4430 call s:create_test_file('Xtestfile2')
4431 new | only
4432 let last_bufnr = bufnr('Test_sv_1', 1)
4433 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4434 cgetexpr l
4435 copen
4436 let numbufs = len(getbufinfo())
4437 exe "normal \<C-W>\<CR>"
4438 copen
4439 exe "normal j\<C-W>\<CR>"
4440 " Make sure new empty buffers are not created
4441 call assert_equal(numbufs, len(getbufinfo()))
4442 " Creating a new buffer should use the next available buffer number
4443 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4444 bwipe Test_sv_1
4445 bwipe Test_sv_2
4446 new | only
4447
4448 " When split opening files from location list window, make sure that two
4449 " windows doesn't refer to the same location list
4450 lgetexpr l
4451 let locid = getloclist(0, {'id' : 0}).id
4452 lopen
4453 exe "normal \<C-W>\<CR>"
4454 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4455 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4456 new | only
4457
4458 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004459 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004460 lhelpgrep window
4461 let locid = getloclist(0, {'id' : 0}).id
4462 lwindow
4463 exe "normal j\<C-W>\<CR>"
4464 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4465 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4466 new | only
4467
Bram Moolenaar406cd902020-02-18 21:54:41 +01004468 " Using :split or :vsplit from a quickfix window should behave like a :new
4469 " or a :vnew command
4470 copen
4471 split
4472 call assert_equal(3, winnr('$'))
4473 let l = getwininfo()
4474 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4475 close
4476 copen
4477 vsplit
4478 let l = getwininfo()
4479 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4480 new | only
4481
Bram Moolenaarb2443732018-11-11 22:50:27 +01004482 call delete('Xtestfile1')
4483 call delete('Xtestfile2')
4484endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004485
4486" Test for parsing entries using visual screen column
4487func Test_viscol()
4488 enew
4489 call writefile(["Col1\tCol2\tCol3"], 'Xfile1')
4490 edit Xfile1
4491
4492 " Use byte offset for column number
4493 set efm&
4494 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4495 call assert_equal([5, 8], [col('.'), virtcol('.')])
4496 cnext
4497 call assert_equal([9, 12], [col('.'), virtcol('.')])
4498 cnext
4499 call assert_equal([14, 20], [col('.'), virtcol('.')])
4500
4501 " Use screen column offset for column number
4502 set efm=%f:%l:%v:%m
4503 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4504 call assert_equal([5, 8], [col('.'), virtcol('.')])
4505 cnext
4506 call assert_equal([9, 12], [col('.'), virtcol('.')])
4507 cnext
4508 call assert_equal([14, 20], [col('.'), virtcol('.')])
4509 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4510 call assert_equal([5, 8], [col('.'), virtcol('.')])
4511 cnext
4512 call assert_equal([10, 16], [col('.'), virtcol('.')])
4513 cnext
4514 call assert_equal([14, 20], [col('.'), virtcol('.')])
4515
4516 enew
4517 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4518
4519 " Use byte offset for column number
4520 set efm&
4521 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4522 call assert_equal([8, 10], [col('.'), virtcol('.')])
4523 cnext
4524 call assert_equal([11, 17], [col('.'), virtcol('.')])
4525 cnext
4526 call assert_equal([16, 25], [col('.'), virtcol('.')])
4527
4528 " Use screen column offset for column number
4529 set efm=%f:%l:%v:%m
4530 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4531 call assert_equal([8, 10], [col('.'), virtcol('.')])
4532 cnext
4533 call assert_equal([11, 17], [col('.'), virtcol('.')])
4534 cnext
4535 call assert_equal([16, 25], [col('.'), virtcol('.')])
4536
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004537 " Use screen column number with a multi-line error message
4538 enew
4539 call writefile(["à test"], 'Xfile1')
4540 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4541 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4542 call assert_equal('Xfile1', @%)
4543 call assert_equal([0, 1, 4, 0], getpos('.'))
4544
4545 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4546 " does not break this
4547 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4548 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4549 call assert_equal('Xfile1', @%)
4550 call assert_equal([0, 1, 3, 0], getpos('.'))
4551
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004552 enew | only
4553 set efm&
4554 call delete('Xfile1')
4555endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004556
4557" Test for the quickfix window buffer
4558func Xqfbuf_test(cchar)
4559 call s:setup_commands(a:cchar)
4560
4561 " Quickfix buffer should be reused across closing and opening a quickfix
4562 " window
4563 Xexpr "F1:10:Line10"
4564 Xopen
4565 let qfbnum = bufnr('')
4566 Xclose
4567 " Even after the quickfix window is closed, the buffer should be loaded
4568 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004569 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004570 Xopen
4571 " Buffer should be reused when opening the window again
4572 call assert_equal(qfbnum, bufnr(''))
4573 Xclose
4574
4575 if a:cchar == 'l'
4576 %bwipe
4577 " For a location list, when both the file window and the location list
4578 " window for the list are closed, then the buffer should be freed.
4579 new | only
4580 lexpr "F1:10:Line10"
4581 let wid = win_getid()
4582 lopen
4583 let qfbnum = bufnr('')
4584 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4585 close
4586 " When the location list window is closed, the buffer name should not
4587 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004588 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004589 call assert_true(bufloaded(qfbnum))
4590
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004591 " After deleting a location list buffer using ":bdelete", opening the
4592 " location list window should mark the buffer as a location list buffer.
4593 exe "bdelete " . qfbnum
4594 lopen
4595 call assert_equal("quickfix", &buftype)
4596 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
4597 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
4598 call assert_false(&swapfile)
4599 lclose
4600
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004601 " When the location list is cleared for the window, the buffer should be
4602 " removed
4603 call setloclist(0, [], 'f')
4604 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004605 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004606
4607 " When the location list is freed with the location list window open, the
4608 " location list buffer should not be lost. It should be reused when the
4609 " location list is again populated.
4610 lexpr "F1:10:Line10"
4611 lopen
4612 let wid = win_getid()
4613 let qfbnum = bufnr('')
4614 wincmd p
4615 call setloclist(0, [], 'f')
4616 lexpr "F1:10:Line10"
4617 lopen
4618 call assert_equal(wid, win_getid())
4619 call assert_equal(qfbnum, bufnr(''))
4620 lclose
4621
4622 " When the window with the location list is closed, the buffer should be
4623 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004624 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004625 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004626 endif
4627endfunc
4628
4629func Test_qfbuf()
4630 call Xqfbuf_test('c')
4631 call Xqfbuf_test('l')
4632endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004633
4634" If there is an autocmd to use only one window, then opening the location
4635" list window used to crash Vim.
4636func Test_winonly_autocmd()
4637 call s:create_test_file('Xtest1')
4638 " Autocmd to show only one Vim window at a time
4639 autocmd WinEnter * only
4640 new
4641 " Load the location list
4642 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
4643 let loclistid = getloclist(0, {'id' : 0}).id
4644 " Open the location list window. Only this window will be shown and the file
4645 " window is closed.
4646 lopen
4647 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4648 " Jump to an entry in the location list and make sure that the cursor is
4649 " positioned correctly.
4650 ll 3
4651 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004652 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004653 call assert_equal(15, line('.'))
4654 " Cleanup
4655 autocmd! WinEnter
4656 new | only
4657 call delete('Xtest1')
4658endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02004659
4660" Test to make sure that an empty quickfix buffer is not reused for loading
4661" a normal buffer.
4662func Test_empty_qfbuf()
4663 enew | only
4664 call writefile(["Test"], 'Xfile1')
4665 call setqflist([], 'f')
4666 copen | only
4667 let qfbuf = bufnr('')
4668 edit Xfile1
4669 call assert_notequal(qfbuf, bufnr(''))
4670 enew
4671 call delete('Xfile1')
4672endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004673
4674" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004675" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004676func Xtest_below(cchar)
4677 call s:setup_commands(a:cchar)
4678
4679 " No quickfix/location list
4680 call assert_fails('Xbelow', 'E42:')
4681 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004682 call assert_fails('Xbefore', 'E42:')
4683 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004684
4685 " Empty quickfix/location list
4686 call g:Xsetlist([])
4687 call assert_fails('Xbelow', 'E42:')
4688 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004689 call assert_fails('Xbefore', 'E42:')
4690 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004691
4692 call s:create_test_file('X1')
4693 call s:create_test_file('X2')
4694 call s:create_test_file('X3')
4695 call s:create_test_file('X4')
4696
4697 " Invalid entries
4698 edit X1
4699 call g:Xsetlist(["E1", "E2"])
4700 call assert_fails('Xbelow', 'E42:')
4701 call assert_fails('Xabove', 'E42:')
4702 call assert_fails('3Xbelow', 'E42:')
4703 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004704 call assert_fails('Xbefore', 'E42:')
4705 call assert_fails('Xafter', 'E42:')
4706 call assert_fails('3Xbefore', 'E42:')
4707 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004708
4709 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004710 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 +02004711 edit +7 X2
4712 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004713 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004714 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004715 normal 7G
4716 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004717 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004718 call assert_fails('Xbefore', 'E553:')
4719
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004720 normal 2j
4721 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004722 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004723 normal 7G
4724 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004725 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004726
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004727 " Last error in this file
4728 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004729 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004730 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004731 normal gg
4732 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004733 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004734 call assert_fails('Xafter', 'E553:')
4735
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004736 " First error in this file
4737 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004738 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004739 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004740 normal G
4741 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004742 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004743 call assert_fails('Xbefore', 'E553:')
4744
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004745 normal gg
4746 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004747 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004748 normal gg
4749 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004750 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004751
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004752 normal G
4753 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004754 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004755 normal G
4756 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004757 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004758
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004759 edit X4
4760 call assert_fails('Xabove', 'E42:')
4761 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004762 call assert_fails('Xbefore', 'E42:')
4763 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004764 if a:cchar == 'l'
4765 " If a buffer has location list entries from some other window but not
4766 " from the current window, then the commands should fail.
4767 edit X1 | split | call setloclist(0, [], 'f')
4768 call assert_fails('Xabove', 'E776:')
4769 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004770 call assert_fails('Xbefore', 'E776:')
4771 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004772 close
4773 endif
4774
4775 " Test for lines with multiple quickfix entries
4776 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3",
4777 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3",
4778 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
4779 edit +1 X2
4780 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004781 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004782 normal 1G
4783 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004784 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004785
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004786 normal gg
4787 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004788 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004789 normal gg
4790 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004791 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004792
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004793 normal G
4794 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004795 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004796 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004797 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004798 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004799
4800 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004801 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004802 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004803 normal G
4804 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004805 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004806
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004807 normal 10G
4808 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004809 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004810 normal 10G$
4811 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004812 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004813
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004814 normal 10G
4815 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004816 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004817 normal 9G
4818 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004819 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004820
4821 " Invalid range
4822 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02004823 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004824 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004825 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02004826 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004827 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004828 endif
4829
4830 call delete('X1')
4831 call delete('X2')
4832 call delete('X3')
4833 call delete('X4')
4834endfunc
4835
4836func Test_cbelow()
4837 call Xtest_below('c')
4838 call Xtest_below('l')
4839endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02004840
4841func Test_quickfix_count()
4842 let commands = [
4843 \ 'cNext',
4844 \ 'cNfile',
4845 \ 'cabove',
4846 \ 'cbelow',
4847 \ 'cfirst',
4848 \ 'clast',
4849 \ 'cnewer',
4850 \ 'cnext',
4851 \ 'cnfile',
4852 \ 'colder',
4853 \ 'cprevious',
4854 \ 'crewind',
4855 \
4856 \ 'lNext',
4857 \ 'lNfile',
4858 \ 'labove',
4859 \ 'lbelow',
4860 \ 'lfirst',
4861 \ 'llast',
4862 \ 'lnewer',
4863 \ 'lnext',
4864 \ 'lnfile',
4865 \ 'lolder',
4866 \ 'lprevious',
4867 \ 'lrewind',
4868 \ ]
4869 for cmd in commands
4870 call assert_fails('-1' .. cmd, 'E16:')
4871 call assert_fails('.' .. cmd, 'E16:')
4872 call assert_fails('%' .. cmd, 'E16:')
4873 call assert_fails('$' .. cmd, 'E16:')
4874 endfor
4875endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02004876
4877" Test for aborting quickfix commands using QuickFixCmdPre
4878func Xtest_qfcmd_abort(cchar)
4879 call s:setup_commands(a:cchar)
4880
4881 call g:Xsetlist([], 'f')
4882
4883 " cexpr/lexpr
4884 let e = ''
4885 try
4886 Xexpr ["F1:10:Line10", "F2:20:Line20"]
4887 catch /.*/
4888 let e = v:exception
4889 endtry
4890 call assert_equal('AbortCmd', e)
4891 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4892
4893 " cfile/lfile
4894 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1')
4895 let e = ''
4896 try
4897 Xfile Xfile1
4898 catch /.*/
4899 let e = v:exception
4900 endtry
4901 call assert_equal('AbortCmd', e)
4902 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4903 call delete('Xfile1')
4904
4905 " cgetbuffer/lgetbuffer
4906 enew!
4907 call append(0, ["F1:10:Line10", "F2:20:Line20"])
4908 let e = ''
4909 try
4910 Xgetbuffer
4911 catch /.*/
4912 let e = v:exception
4913 endtry
4914 call assert_equal('AbortCmd', e)
4915 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4916 enew!
4917
4918 " vimgrep/lvimgrep
4919 let e = ''
4920 try
4921 Xvimgrep /func/ test_quickfix.vim
4922 catch /.*/
4923 let e = v:exception
4924 endtry
4925 call assert_equal('AbortCmd', e)
4926 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4927
4928 " helpgrep/lhelpgrep
4929 let e = ''
4930 try
4931 Xhelpgrep quickfix
4932 catch /.*/
4933 let e = v:exception
4934 endtry
4935 call assert_equal('AbortCmd', e)
4936 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4937
4938 " grep/lgrep
4939 if has('unix')
4940 let e = ''
4941 try
4942 silent Xgrep func test_quickfix.vim
4943 catch /.*/
4944 let e = v:exception
4945 endtry
4946 call assert_equal('AbortCmd', e)
4947 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4948 endif
4949endfunc
4950
4951func Test_qfcmd_abort()
4952 augroup QF_Test
4953 au!
4954 autocmd QuickFixCmdPre * throw "AbortCmd"
4955 augroup END
4956
4957 call Xtest_qfcmd_abort('c')
4958 call Xtest_qfcmd_abort('l')
4959
4960 augroup QF_Test
4961 au!
4962 augroup END
4963endfunc
4964
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004965" Test for using a file in one of the parent directories.
4966func Test_search_in_dirstack()
4967 call mkdir('Xtestdir/a/b/c', 'p')
4968 let save_cwd = getcwd()
4969 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
4970 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
4971 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
4972 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
4973
4974 let lines = "Entering dir Xtestdir\n" .
4975 \ "Entering dir a\n" .
4976 \ "Entering dir b\n" .
4977 \ "Xfile2:2:X2_L2\n" .
4978 \ "Leaving dir a\n" .
4979 \ "Xfile1:2:X1_L2\n" .
4980 \ "Xfile3:1:X3_L1\n" .
4981 \ "Entering dir c\n" .
4982 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004983 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004984 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004985 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004986 call assert_equal(11, getqflist({'size' : 0}).size)
4987 call assert_equal(4, getqflist({'idx' : 0}).idx)
4988 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004989 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004990 cnext
4991 call assert_equal(6, getqflist({'idx' : 0}).idx)
4992 call assert_equal('X1_L2', getline('.'))
4993 cnext
4994 call assert_equal(7, getqflist({'idx' : 0}).idx)
4995 call assert_equal(1, line('$'))
4996 call assert_equal('', getline(1))
4997 cnext
4998 call assert_equal(9, getqflist({'idx' : 0}).idx)
4999 call assert_equal(1, line('$'))
5000 call assert_equal('', getline(1))
5001
5002 set efm&
5003 exe 'cd ' . save_cwd
5004 call delete('Xtestdir', 'rf')
5005endfunc
5006
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005007" Test for :cquit
5008func Test_cquit()
5009 " Exit Vim with a non-zero value
5010 if RunVim([], ["cquit 7"], '')
5011 call assert_equal(7, v:shell_error)
5012 endif
5013
5014 if RunVim([], ["50cquit"], '')
5015 call assert_equal(50, v:shell_error)
5016 endif
5017
5018 " Exit Vim with default value
5019 if RunVim([], ["cquit"], '')
5020 call assert_equal(1, v:shell_error)
5021 endif
5022
5023 " Exit Vim with zero value
5024 if RunVim([], ["cquit 0"], '')
5025 call assert_equal(0, v:shell_error)
5026 endif
5027
5028 " Exit Vim with negative value
5029 call assert_fails('-3cquit', 'E16:')
5030endfunc
5031
Bram Moolenaar858ba062020-05-31 23:11:59 +02005032" Test for getting a specific item from a quickfix list
5033func Xtest_getqflist_by_idx(cchar)
5034 call s:setup_commands(a:cchar)
5035 " Empty list
5036 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5037 Xexpr ['F1:10:L10', 'F1:20:L20']
5038 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5039 call assert_equal(bufnr('F1'), l[0].bufnr)
5040 call assert_equal(20, l[0].lnum)
5041 call assert_equal('L20', l[0].text)
5042 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5043 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
5044 %bwipe!
5045endfunc
5046
5047func Test_getqflist_by_idx()
5048 call Xtest_getqflist_by_idx('c')
5049 call Xtest_getqflist_by_idx('l')
5050endfunc
5051
5052" Test for the 'quickfixtextfunc' setting
5053func Tqfexpr(info)
5054 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005055 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005056 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005057 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005058 endif
5059
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005060 let l = []
5061 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5062 let e = qfl[idx]
5063 let s = ''
5064 if e.bufnr != 0
5065 let bname = bufname(e.bufnr)
5066 let s ..= fnamemodify(bname, ':.')
5067 endif
5068 let s ..= '-'
5069 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5070 let s ..= e.text
5071 call add(l, s)
5072 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005073
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005074 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005075endfunc
5076
5077func Xtest_qftextfunc(cchar)
5078 call s:setup_commands(a:cchar)
5079
5080 set efm=%f:%l:%c:%m
5081 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005082 call assert_equal('Tqfexpr', &quickfixtextfunc)
5083 call assert_equal('',
5084 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005085 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5086 Xwindow
5087 call assert_equal('F1-L10C2-green', getline(1))
5088 call assert_equal('F1-L20C4-blue', getline(2))
5089 Xclose
5090 set quickfixtextfunc&vim
5091 Xwindow
5092 call assert_equal('F1|10 col 2| green', getline(1))
5093 call assert_equal('F1|20 col 4| blue', getline(2))
5094 Xclose
5095 set efm&
5096 set quickfixtextfunc&
5097
5098 " Test for per list 'quickfixtextfunc' setting
5099 func PerQfText(info)
5100 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005101 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005102 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005103 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005104 endif
5105 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005106 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005107 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005108 let l = []
5109 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5110 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5111 endfor
5112 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005113 endfunc
5114 set quickfixtextfunc=Tqfexpr
5115 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5116 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5117 Xwindow
5118 call assert_equal('Line 10, Col 2', getline(1))
5119 call assert_equal('Line 20, Col 4', getline(2))
5120 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005121 call assert_equal(function('PerQfText'),
5122 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005123 " Add entries to the list when the quickfix buffer is hidden
5124 Xaddexpr ['F1:30:6:red']
5125 Xwindow
5126 call assert_equal('Line 30, Col 6', getline(3))
5127 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005128 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005129 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005130 set quickfixtextfunc&
5131 delfunc PerQfText
5132
5133 " Non-existing function
5134 set quickfixtextfunc=Tabc
5135 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5136 call assert_fails("Xwindow", 'E117:')
5137 Xclose
5138 set quickfixtextfunc&
5139
5140 " set option to a non-function
5141 set quickfixtextfunc=[10,\ 20]
5142 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5143 call assert_fails("Xwindow", 'E117:')
5144 Xclose
5145 set quickfixtextfunc&
5146
5147 " set option to a function with different set of arguments
5148 func Xqftext(a, b, c)
5149 return a:a .. a:b .. a:c
5150 endfunc
5151 set quickfixtextfunc=Xqftext
5152 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5153 call assert_fails("Xwindow", 'E119:')
5154 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005155
5156 " set option to a function that returns a list with non-strings
5157 func Xqftext2(d)
5158 return ['one', [], 'two']
5159 endfunc
5160 set quickfixtextfunc=Xqftext2
5161 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5162 \ 'E730:')
5163 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005164 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5165 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005166 Xclose
5167
Bram Moolenaar858ba062020-05-31 23:11:59 +02005168 set quickfixtextfunc&
5169 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005170 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005171
5172 " set the global option to a lambda function
5173 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5174 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5175 Xwindow
5176 call assert_equal(['green', 'blue'], getline(1, '$'))
5177 Xclose
5178 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)
5179 set quickfixtextfunc&
5180
5181 " use a lambda function that returns an empty list
5182 set quickfixtextfunc={d\ ->\ []}
5183 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5184 Xwindow
5185 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5186 \ getline(1, '$'))
5187 Xclose
5188 set quickfixtextfunc&
5189
5190 " use a lambda function that returns a list with empty strings
5191 set quickfixtextfunc={d\ ->\ ['',\ '']}
5192 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5193 Xwindow
5194 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5195 \ getline(1, '$'))
5196 Xclose
5197 set quickfixtextfunc&
5198
5199 " set the per-quickfix list text function to a lambda function
5200 call g:Xsetlist([], ' ',
5201 \ {'quickfixtextfunc' :
5202 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5203 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5204 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5205 Xwindow
5206 call assert_equal('Line 10, Col 2', getline(1))
5207 call assert_equal('Line 20, Col 4', getline(2))
5208 Xclose
5209 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5210 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005211endfunc
5212
5213func Test_qftextfunc()
5214 call Xtest_qftextfunc('c')
5215 call Xtest_qftextfunc('l')
5216endfunc
5217
Bram Moolenaarec98e932020-06-08 19:35:59 +02005218" Running :lhelpgrep command more than once in a help window, doesn't jump to
5219" the help topic
5220func Test_lhelpgrep_from_help_window()
5221 call mkdir('Xtestdir/doc', 'p')
5222 call writefile(['window'], 'Xtestdir/doc/a.txt')
5223 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5224 let save_rtp = &rtp
5225 let &rtp = 'Xtestdir'
5226 lhelpgrep window
5227 lhelpgrep buffer
5228 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5229 lhelpgrep window
5230 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5231 let &rtp = save_rtp
5232 call delete('Xtestdir', 'rf')
5233 new | only!
5234endfunc
5235
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005236" Test for the crash fixed by 7.3.715
5237func Test_setloclist_crash()
5238 %bw!
5239 let g:BufNum = bufnr()
5240 augroup QF_Test
5241 au!
5242 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5243 augroup END
5244
5245 try
5246 lvimgrep /.*/ *.mak
5247 catch /E926:/
5248 endtry
5249 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5250 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5251
5252 augroup QF_Test
5253 au!
5254 augroup END
5255 unlet g:BufNum
5256 %bw!
5257endfunc
5258
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005259" Test for adding an invalid entry with the quickfix window open and making
5260" sure that the window contents are not changed
5261func Test_add_invalid_entry_with_qf_window()
5262 call setqflist([], 'f')
5263 cexpr "Xfile1:10:aa"
5264 copen
5265 call setqflist(['bb'], 'a')
5266 call assert_equal(1, line('$'))
5267 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
5268 call assert_equal([{'lnum': 10, 'bufnr': bufnr('Xfile1'), 'col': 0, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': 'aa'}], getqflist())
5269 cclose
5270endfunc
5271
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005272" Test for very weird problem: autocommand causes a failure, resulting opening
5273" the quickfix window to fail. This still splits the window, but otherwise
5274" should not mess up buffers.
5275func Test_quickfix_window_fails_to_open()
5276 CheckScreendump
5277
5278 let lines =<< trim END
5279 anything
5280 try
5281 anything
5282 endtry
5283 END
5284 call writefile(lines, 'XquickfixFails')
5285
5286 let lines =<< trim END
5287 split XquickfixFails
5288 silent vimgrep anything %
5289 normal o
5290 au BufLeave * ++once source XquickfixFails
5291 " This will trigger the autocommand, which causes an error, what follows
5292 " is aborted but the window was already split.
5293 silent! cwindow
5294 END
5295 call writefile(lines, 'XtestWinFails')
5296 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
5297 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
5298
5299 " clean up
5300 call term_sendkeys(buf, ":bwipe!\<CR>")
5301 call term_wait(buf)
5302 call StopVimInTerminal(buf)
5303 call delete('XtestWinFails')
5304 call delete('XquickfixFails')
5305endfunc
5306
Bram Moolenaar2d870f82020-12-05 13:41:01 +01005307" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01005308" is changed.
5309func Xqfbuf_update(cchar)
5310 call s:setup_commands(a:cchar)
5311
5312 Xexpr "F1:1:line1"
5313 Xopen
5314 call assert_equal(['F1|1| line1'], getline(1, '$'))
5315 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5316
5317 " Test setqflist() using the 'lines' key in 'what'
5318 " add a new entry
5319 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
5320 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
5321 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5322 " replace all the entries with a single entry
5323 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
5324 call assert_equal(['F3|3| line3'], getline(1, '$'))
5325 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5326 " remove all the entries
5327 call g:Xsetlist([], 'r', {'lines' : []})
5328 call assert_equal([''], getline(1, '$'))
5329 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5330 " add a new list
5331 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
5332 call assert_equal(['F4|4| line4'], getline(1, '$'))
5333 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5334
5335 " Test setqflist() using the 'items' key in 'what'
5336 " add a new entry
5337 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
5338 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
5339 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5340 " replace all the entries with a single entry
5341 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
5342 call assert_equal(['F6|6| line6'], getline(1, '$'))
5343 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5344 " remove all the entries
5345 call g:Xsetlist([], 'r', {'items' : []})
5346 call assert_equal([''], getline(1, '$'))
5347 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5348 " add a new list
5349 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
5350 call assert_equal(['F7|7| line7'], getline(1, '$'))
5351 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5352
5353 call g:Xsetlist([], ' ', {})
5354 call assert_equal([''], getline(1, '$'))
5355 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5356
5357 Xclose
5358endfunc
5359
5360func Test_qfbuf_update()
5361 call Xqfbuf_update('c')
5362 call Xqfbuf_update('l')
5363endfunc
5364
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005365" vim: shiftwidth=2 sts=2 expandtab