blob: 8667631d3b6339e3005bf66f5ac5adf173b072ff [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 Moolenaar1c299432018-10-28 14:36:09 +01002868" Test for incsearch highlighting of the :vimgrep pattern
2869" This test used to cause "E315: ml_get: invalid lnum" errors.
2870func Test_vimgrep_incsearch()
2871 enew
2872 set incsearch
2873 call test_override("char_avail", 1)
2874
2875 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
2876 let l = getqflist()
2877 call assert_equal(2, len(l))
2878
2879 call test_override("ALL", 0)
2880 set noincsearch
2881endfunc
2882
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01002883" Test vimgrep with the last search pattern not set
2884func Test_vimgrep_with_no_last_search_pat()
2885 let lines =<< trim [SCRIPT]
2886 call assert_fails('vimgrep // *', 'E35:')
2887 call writefile(v:errors, 'Xresult')
2888 qall!
2889 [SCRIPT]
2890 call writefile(lines, 'Xscript')
2891 if RunVim([], [], '--clean -S Xscript')
2892 call assert_equal([], readfile('Xresult'))
2893 endif
2894 call delete('Xscript')
2895 call delete('Xresult')
2896endfunc
2897
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02002898" Test vimgrep without swap file
2899func Test_vimgrep_without_swap_file()
2900 let lines =<< trim [SCRIPT]
2901 vimgrep grep test_c*
2902 call writefile(['done'], 'Xresult')
2903 qall!
2904 [SCRIPT]
2905 call writefile(lines, 'Xscript')
2906 if RunVim([], [], '--clean -n -S Xscript Xscript')
2907 call assert_equal(['done'], readfile('Xresult'))
2908 endif
2909 call delete('Xscript')
2910 call delete('Xresult')
2911endfunc
2912
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002913func Test_vimgrep_existing_swapfile()
2914 call writefile(['match apple with apple'], 'Xapple')
2915 call writefile(['swapfile'], '.Xapple.swp')
2916 let g:foundSwap = 0
2917 let g:ignoreSwapExists = 1
2918 augroup grep
2919 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
2920 augroup END
2921 vimgrep apple Xapple
2922 call assert_equal(1, g:foundSwap)
2923 call assert_match('.Xapple.swo', swapname(''))
2924
2925 call delete('Xapple')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002926 call delete('.Xapple.swp')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002927 augroup grep
2928 au! SwapExists
2929 augroup END
2930 unlet g:ignoreSwapExists
2931endfunc
2932
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002933func XfreeTests(cchar)
2934 call s:setup_commands(a:cchar)
2935
2936 enew | only
2937
2938 " Deleting the quickfix stack should work even When the current list is
2939 " somewhere in the middle of the stack
2940 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2941 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2942 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2943 Xolder
2944 call g:Xsetlist([], 'f')
2945 call assert_equal(0, len(g:Xgetlist()))
2946
2947 " After deleting the stack, adding a new list should create a stack with a
2948 " single list.
2949 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2950 call assert_equal(1, g:Xgetlist({'all':1}).nr)
2951
2952 " Deleting the stack from a quickfix window should update/clear the
2953 " quickfix/location list window.
2954 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2955 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2956 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2957 Xolder
2958 Xwindow
2959 call g:Xsetlist([], 'f')
2960 call assert_equal(2, winnr('$'))
2961 call assert_equal(1, line('$'))
2962 Xclose
2963
2964 " Deleting the stack from a non-quickfix window should update/clear the
2965 " quickfix/location list window.
2966 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2967 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2968 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2969 Xolder
2970 Xwindow
2971 wincmd p
2972 call g:Xsetlist([], 'f')
2973 call assert_equal(0, len(g:Xgetlist()))
2974 wincmd p
2975 call assert_equal(2, winnr('$'))
2976 call assert_equal(1, line('$'))
2977
2978 " After deleting the location list stack, if the location list window is
2979 " opened, then a new location list should be created. So opening the
2980 " location list window again should not create a new window.
2981 if a:cchar == 'l'
2982 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2983 wincmd p
2984 lopen
2985 call assert_equal(2, winnr('$'))
2986 endif
2987 Xclose
2988endfunc
2989
Bram Moolenaar74240d32017-12-10 15:26:15 +01002990" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002991func Test_qf_free()
2992 call XfreeTests('c')
2993 call XfreeTests('l')
2994endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02002995
2996" Test for buffer overflow when parsing lines and adding new entries to
2997" the quickfix list.
2998func Test_bufoverflow()
2999 set efm=%f:%l:%m
3000 cgetexpr ['File1:100:' . repeat('x', 1025)]
3001
3002 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3003 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3004
3005 set efm=%DEntering\ directory\ %f,%f:%l:%m
3006 cgetexpr ['Entering directory ' . repeat('a', 1006),
3007 \ 'File1:10:Hello World']
3008 set efm&vim
3009endfunc
3010
Bram Moolenaar875feea2017-06-11 16:07:51 +02003011" Tests for getting the quickfix stack size
3012func XsizeTests(cchar)
3013 call s:setup_commands(a:cchar)
3014
3015 call g:Xsetlist([], 'f')
3016 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003017 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3018 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003019
3020 Xexpr "File1:10:Line1"
3021 Xexpr "File2:20:Line2"
3022 Xexpr "File3:30:Line3"
3023 Xolder | Xolder
3024 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3025 call g:Xsetlist([], 'f')
3026
3027 Xexpr "File1:10:Line1"
3028 Xexpr "File2:20:Line2"
3029 Xexpr "File3:30:Line3"
3030 Xolder | Xolder
3031 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3032 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3033endfunc
3034
3035func Test_Qf_Size()
3036 call XsizeTests('c')
3037 call XsizeTests('l')
3038endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003039
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003040func Test_cclose_from_copen()
3041 augroup QF_Test
3042 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003043 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003044 augroup END
3045 copen
3046 augroup QF_Test
3047 au!
3048 augroup END
3049 augroup! QF_Test
3050endfunc
3051
Bram Moolenaar18141832017-06-25 21:17:25 +02003052func Test_cclose_in_autocmd()
3053 " Problem is only triggered if "starting" is zero, so that the OptionsSet
3054 " event will be triggered.
3055 call test_override('starting', 1)
3056 augroup QF_Test
3057 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003058 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003059 augroup END
3060 copen
3061 augroup QF_Test
3062 au!
3063 augroup END
3064 augroup! QF_Test
3065 call test_override('starting', 0)
3066endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003067
Bram Moolenaar379fb762018-08-30 15:58:28 +02003068" Check that ":file" without an argument is possible even when "curbuf_lock"
3069" is set.
3070func Test_file_from_copen()
3071 " Works without argument.
3072 augroup QF_Test
3073 au!
3074 au FileType qf file
3075 augroup END
3076 copen
3077
3078 augroup QF_Test
3079 au!
3080 augroup END
3081 cclose
3082
3083 " Fails with argument.
3084 augroup QF_Test
3085 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003086 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003087 augroup END
3088 copen
3089 augroup QF_Test
3090 au!
3091 augroup END
3092 cclose
3093
3094 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003095endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003096
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003097func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003098 augroup QF_Test
3099 au!
3100 au FileType qf resize 5
3101 augroup END
3102 try
3103 " This should succeed without any exception. No other buffers are
3104 " involved in the autocmd.
3105 copen
3106 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003107 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003108 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003109 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003110 augroup! QF_Test
3111 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003112endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003113
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003114func Test_vimgrep_with_textlock()
3115 new
3116
3117 " Simple way to execute something with "textwinlock" set.
3118 " Check that vimgrep without jumping can be executed.
3119 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3120 normal ax
3121 let qflist = getqflist()
3122 call assert_true(len(qflist) > 0)
3123 call assert_match('RunTheTest', qflist[0].text)
3124 call setqflist([], 'r')
3125 au! InsertCharPre
3126
3127 " Check that vimgrepadd without jumping can be executed.
3128 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3129 normal ax
3130 let qflist = getqflist()
3131 call assert_true(len(qflist) > 0)
3132 call assert_match('RunTheTest', qflist[0].text)
3133 call setqflist([], 'r')
3134 au! InsertCharPre
3135
3136 " Check that lvimgrep without jumping can be executed.
3137 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3138 normal ax
3139 let qflist = getloclist(0)
3140 call assert_true(len(qflist) > 0)
3141 call assert_match('RunTheTest', qflist[0].text)
3142 call setloclist(0, [], 'r')
3143 au! InsertCharPre
3144
3145 " Check that lvimgrepadd without jumping can be executed.
3146 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3147 normal ax
3148 let qflist = getloclist(0)
3149 call assert_true(len(qflist) > 0)
3150 call assert_match('RunTheTest', qflist[0].text)
3151 call setloclist(0, [], 'r')
3152 au! InsertCharPre
3153
3154 " trying to jump will give an error
3155 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3156 call assert_fails('normal ax', 'E565:')
3157 au! InsertCharPre
3158
3159 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3160 call assert_fails('normal ax', 'E565:')
3161 au! InsertCharPre
3162
3163 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3164 call assert_fails('normal ax', 'E565:')
3165 au! InsertCharPre
3166
3167 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3168 call assert_fails('normal ax', 'E565:')
3169 au! InsertCharPre
3170
3171 bwipe!
3172endfunc
3173
Bram Moolenaara8788f42017-07-19 17:06:20 +02003174" Tests for the quickfix buffer b:changedtick variable
3175func Xchangedtick_tests(cchar)
3176 call s:setup_commands(a:cchar)
3177
3178 new | only
3179
3180 Xexpr "" | Xexpr "" | Xexpr ""
3181
3182 Xopen
3183 Xolder
3184 Xolder
3185 Xaddexpr "F1:10:Line10"
3186 Xaddexpr "F2:20:Line20"
3187 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3188 call g:Xsetlist([], 'f')
3189 call assert_equal(8, getbufvar('%', 'changedtick'))
3190 Xclose
3191endfunc
3192
3193func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003194 call Xchangedtick_tests('c')
3195 call Xchangedtick_tests('l')
3196endfunc
3197
3198" Tests for parsing an expression using setqflist()
3199func Xsetexpr_tests(cchar)
3200 call s:setup_commands(a:cchar)
3201
3202 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003203 call g:Xsetlist([], ' ', {'lines' : t})
3204 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003205
3206 let l = g:Xgetlist()
3207 call assert_equal(3, len(l))
3208 call assert_equal(20, l[1].lnum)
3209 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003210 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003211 let l = g:Xgetlist()
3212 call assert_equal(1, len(l))
3213 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003214 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3215 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003216
3217 call g:Xsetlist([], 'f')
3218 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003219 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3220 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3221 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3222 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003223 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3224 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003225
3226 " Adding entries using a custom efm
3227 set efm&
3228 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3229 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3230 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3231 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3232 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3233 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3234 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3235 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003236endfunc
3237
3238func Test_setexpr()
3239 call Xsetexpr_tests('c')
3240 call Xsetexpr_tests('l')
3241endfunc
3242
3243" Tests for per quickfix/location list directory stack
3244func Xmultidirstack_tests(cchar)
3245 call s:setup_commands(a:cchar)
3246
3247 call g:Xsetlist([], 'f')
3248 Xexpr "" | Xexpr ""
3249
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003250 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3251 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3252 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3253 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003254
3255 let l1 = g:Xgetlist({'nr':1, 'items':1})
3256 let l2 = g:Xgetlist({'nr':2, 'items':1})
3257 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3258 call assert_equal(3, l1.items[1].lnum)
3259 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3260 call assert_equal(5, l2.items[1].lnum)
3261endfunc
3262
3263func Test_multidirstack()
3264 call mkdir('Xone/a', 'p')
3265 call mkdir('Xtwo/a', 'p')
3266 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3267 call writefile(lines, 'Xone/a/one.txt')
3268 call writefile(lines, 'Xtwo/a/two.txt')
3269 let save_efm = &efm
3270 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3271
3272 call Xmultidirstack_tests('c')
3273 call Xmultidirstack_tests('l')
3274
3275 let &efm = save_efm
3276 call delete('Xone', 'rf')
3277 call delete('Xtwo', 'rf')
3278endfunc
3279
3280" Tests for per quickfix/location list file stack
3281func Xmultifilestack_tests(cchar)
3282 call s:setup_commands(a:cchar)
3283
3284 call g:Xsetlist([], 'f')
3285 Xexpr "" | Xexpr ""
3286
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003287 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3288 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3289 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3290 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003291
3292 let l1 = g:Xgetlist({'nr':1, 'items':1})
3293 let l2 = g:Xgetlist({'nr':2, 'items':1})
3294 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3295 call assert_equal(3, l1.items[1].lnum)
3296 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3297 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003298
3299 " Test for start of a new error line in the same line where a previous
3300 " error line ends with a file stack.
3301 let efm_val = 'Error\ l%l\ in\ %f,'
3302 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
3303 let l = g:Xgetlist({'lines' : [
3304 \ '(one.txt',
3305 \ 'Error l4 in one.txt',
3306 \ ') (two.txt',
3307 \ 'Error l6 in two.txt',
3308 \ ')',
3309 \ 'Error l8 in one.txt'
3310 \ ], 'efm' : efm_val})
3311 call assert_equal(3, len(l.items))
3312 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3313 call assert_equal(4, l.items[0].lnum)
3314 call assert_equal('one.txt', l.items[0].text)
3315 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3316 call assert_equal(6, l.items[1].lnum)
3317 call assert_equal('two.txt', l.items[1].text)
3318 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3319 call assert_equal(8, l.items[2].lnum)
3320 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003321endfunc
3322
3323func Test_multifilestack()
3324 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3325 call writefile(lines, 'one.txt')
3326 call writefile(lines, 'two.txt')
3327 let save_efm = &efm
3328 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3329
3330 call Xmultifilestack_tests('c')
3331 call Xmultifilestack_tests('l')
3332
3333 let &efm = save_efm
3334 call delete('one.txt')
3335 call delete('two.txt')
3336endfunc
3337
3338" Tests for per buffer 'efm' setting
3339func Test_perbuf_efm()
3340 call writefile(["File1-10-Line10"], 'one.txt')
3341 call writefile(["File2#20#Line20"], 'two.txt')
3342 set efm=%f#%l#%m
3343 new | only
3344 new
3345 setlocal efm=%f-%l-%m
3346 cfile one.txt
3347 wincmd w
3348 caddfile two.txt
3349
3350 let l = getqflist()
3351 call assert_equal(10, l[0].lnum)
3352 call assert_equal('Line20', l[1].text)
3353
3354 set efm&
3355 new | only
3356 call delete('one.txt')
3357 call delete('two.txt')
Bram Moolenaara8788f42017-07-19 17:06:20 +02003358endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003359
3360" Open multiple help windows using ":lhelpgrep
3361" This test used to crash Vim
3362func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003363 new | only
3364 lhelpgrep window
3365 lopen
3366 e#
3367 lhelpgrep buffer
3368 call assert_equal(3, winnr('$'))
3369 call assert_true(len(getloclist(1)) != 0)
3370 call assert_true(len(getloclist(2)) != 0)
3371 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003372endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003373
3374" Tests for adding new quickfix lists using setqflist()
3375func XaddQf_tests(cchar)
3376 call s:setup_commands(a:cchar)
3377
3378 " Create a new list using ' ' for action
3379 call g:Xsetlist([], 'f')
3380 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3381 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3382 call assert_equal(1, l.nr)
3383 call assert_equal('Test1', l.title)
3384
3385 " Create a new list using ' ' for action and '$' for 'nr'
3386 call g:Xsetlist([], 'f')
3387 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3388 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3389 call assert_equal(1, l.nr)
3390 call assert_equal('Test2', l.title)
3391
3392 " Create a new list using 'a' for action
3393 call g:Xsetlist([], 'f')
3394 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3395 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3396 call assert_equal(1, l.nr)
3397 call assert_equal('Test3', l.title)
3398
3399 " Create a new list using 'a' for action and '$' for 'nr'
3400 call g:Xsetlist([], 'f')
3401 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3402 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3403 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3404 call assert_equal(1, l.nr)
3405 call assert_equal('Test4', l.title)
3406
3407 " Adding a quickfix list should remove all the lists following the current
3408 " list.
3409 Xexpr "" | Xexpr "" | Xexpr ""
3410 silent! 10Xolder
3411 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3412 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3413 call assert_equal(2, l.nr)
3414 call assert_equal('Test5', l.title)
3415
3416 " Add a quickfix list using '$' as the list number.
3417 let lastqf = g:Xgetlist({'nr':'$'}).nr
3418 silent! 99Xolder
3419 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3420 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3421 call assert_equal(lastqf + 1, l.nr)
3422 call assert_equal('Test6', l.title)
3423
3424 " Add a quickfix list using 'nr' set to one more than the quickfix
3425 " list size.
3426 let lastqf = g:Xgetlist({'nr':'$'}).nr
3427 silent! 99Xolder
3428 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3429 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3430 call assert_equal(lastqf + 1, l.nr)
3431 call assert_equal('Test7', l.title)
3432
3433 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3434 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3435 silent! 99Xolder
3436 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3437 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3438 call assert_equal(10, l.nr)
3439 call assert_equal('Test8', l.title)
3440
3441 " Add a quickfix list using 'nr' set to a value greater than 10
3442 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3443
3444 " Try adding a quickfix list with 'nr' set to a value greater than the
3445 " quickfix list size but less than 10.
3446 call g:Xsetlist([], 'f')
3447 Xexpr "" | Xexpr "" | Xexpr ""
3448 silent! 99Xolder
3449 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3450
3451 " Add a quickfix list using 'nr' set to a some string or list
3452 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3453endfunc
3454
3455func Test_add_qf()
3456 call XaddQf_tests('c')
3457 call XaddQf_tests('l')
3458endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003459
3460" Test for getting the quickfix list items from some text without modifying
3461" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003462func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003463 call s:setup_commands(a:cchar)
3464 call g:Xsetlist([], 'f')
3465
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003466 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003467 call assert_equal(2, len(l))
3468 call assert_equal(30, l[1].lnum)
3469
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003470 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3471 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3472 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3473 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003474
Bram Moolenaar36538222017-09-02 19:51:44 +02003475 " Parse text using a custom efm
3476 set efm&
3477 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3478 call assert_equal('Line30', l[0].text)
3479 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3480 call assert_equal('File3:30:Line30', l[0].text)
3481 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3482 call assert_equal({}, l)
3483 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3484 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3485
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003486 " Make sure that the quickfix stack is not modified
3487 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3488endfunc
3489
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003490func Test_get_list_from_lines()
3491 call XgetListFromLines('c')
3492 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003493endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003494
3495" Tests for the quickfix list id
3496func Xqfid_tests(cchar)
3497 call s:setup_commands(a:cchar)
3498
3499 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003500 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003501 Xexpr ''
3502 let start_id = g:Xgetlist({'id' : 0}).id
3503 Xexpr '' | Xexpr ''
3504 Xolder
3505 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3506 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3507 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003508 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003509 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003510 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3511 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003512
3513 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3514 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003515 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003516 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3517 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3518 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3519
3520 let qfid = g:Xgetlist({'id':0, 'nr':0})
3521 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003522 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003523endfunc
3524
3525func Test_qf_id()
3526 call Xqfid_tests('c')
3527 call Xqfid_tests('l')
3528endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003529
3530func Xqfjump_tests(cchar)
3531 call s:setup_commands(a:cchar)
3532
3533 call writefile(["Line1\tFoo", "Line2"], 'F1')
3534 call writefile(["Line1\tBar", "Line2"], 'F2')
3535 call writefile(["Line1\tBaz", "Line2"], 'F3')
3536
3537 call g:Xsetlist([], 'f')
3538
3539 " Tests for
3540 " Jumping to a line using a pattern
3541 " Jumping to a column greater than the last column in a line
3542 " Jumping to a line greater than the last line in the file
3543 let l = []
3544 for i in range(1, 7)
3545 call add(l, {})
3546 endfor
3547 let l[0].filename='F1'
3548 let l[0].pattern='Line1'
3549 let l[1].filename='F2'
3550 let l[1].pattern='Line1'
3551 let l[2].filename='F3'
3552 let l[2].pattern='Line1'
3553 let l[3].filename='F3'
3554 let l[3].lnum=1
3555 let l[3].col=9
3556 let l[3].vcol=1
3557 let l[4].filename='F3'
3558 let l[4].lnum=99
3559 let l[5].filename='F3'
3560 let l[5].lnum=1
3561 let l[5].col=99
3562 let l[5].vcol=1
3563 let l[6].filename='F3'
3564 let l[6].pattern='abcxyz'
3565
3566 call g:Xsetlist([], ' ', {'items' : l})
3567 Xopen | only
3568 2Xnext
3569 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003570 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003571 Xnext
3572 call assert_equal(7, col('.'))
3573 Xnext
3574 call assert_equal(2, line('.'))
3575 Xnext
3576 call assert_equal(9, col('.'))
3577 2
3578 Xnext
3579 call assert_equal(2, line('.'))
3580
3581 if a:cchar == 'l'
3582 " When jumping to a location list entry in the location list window and
3583 " no usable windows are available, then a new window should be opened.
3584 enew! | new | only
3585 call g:Xsetlist([], 'f')
3586 setlocal buftype=nofile
3587 new
3588 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']})
3589 Xopen
3590 let winid = win_getid()
3591 wincmd p
3592 close
3593 call win_gotoid(winid)
3594 Xnext
3595 call assert_equal(3, winnr('$'))
3596 call assert_equal(1, winnr())
3597 call assert_equal(2, line('.'))
3598
3599 " When jumping to an entry in the location list window and the window
3600 " associated with the location list is not present and a window containing
3601 " the file is already present, then that window should be used.
3602 close
3603 belowright new
3604 call g:Xsetlist([], 'f')
3605 edit F3
3606 call win_gotoid(winid)
3607 Xlast
3608 call assert_equal(3, winnr())
3609 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3610 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3611 endif
3612
3613 " Cleanup
3614 enew!
3615 new | only
3616
3617 call delete('F1')
3618 call delete('F2')
3619 call delete('F3')
3620endfunc
3621
3622func Test_qfjump()
3623 call Xqfjump_tests('c')
3624 call Xqfjump_tests('l')
3625endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003626
3627" Tests for the getqflist() and getloclist() functions when the list is not
3628" present or is empty
3629func Xgetlist_empty_tests(cchar)
3630 call s:setup_commands(a:cchar)
3631
3632 " Empty quickfix stack
3633 call g:Xsetlist([], 'f')
3634 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3635 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3636 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3637 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3638 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3639 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3640 call assert_equal('', g:Xgetlist({'title' : 0}).title)
3641 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003642 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003643 if a:cchar == 'c'
3644 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003645 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003646 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
3647 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003648 else
3649 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3650 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003651 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003652 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003653 \ g:Xgetlist({'all' : 0}))
3654 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003655
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003656 " Quickfix window with empty stack
3657 silent! Xopen
3658 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003659 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003660 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3661 Xclose
3662
Bram Moolenaara6d48492017-12-12 22:45:31 +01003663 " Empty quickfix list
3664 Xexpr ""
3665 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3666 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3667 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3668 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3669 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3670 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3671 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3672 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003673 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003674
3675 let qfid = g:Xgetlist({'id' : 0}).id
3676 call g:Xsetlist([], 'f')
3677
3678 " Non-existing quickfix identifier
3679 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3680 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3681 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3682 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3683 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3684 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3685 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3686 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003687 call assert_equal(0, g:Xgetlist({'id' : qfid, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003688 if a:cchar == 'c'
3689 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3690 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003691 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003692 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3693 else
3694 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3695 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003696 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3697 \ 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003698 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
3699 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003700
3701 " Non-existing quickfix list number
3702 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3703 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3704 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3705 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3706 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3707 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3708 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3709 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003710 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003711 if a:cchar == 'c'
3712 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3713 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003714 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
3715 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003716 else
3717 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3718 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003719 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3720 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003721 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003722endfunc
3723
3724func Test_getqflist()
3725 call Xgetlist_empty_tests('c')
3726 call Xgetlist_empty_tests('l')
3727endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01003728
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01003729func Test_getqflist_invalid_nr()
3730 " The following commands used to crash Vim
3731 cexpr ""
3732 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3733
3734 " Cleanup
3735 call setqflist([], 'r')
3736endfunc
3737
Bram Moolenaarb254af32017-12-18 19:48:58 +01003738" Tests for the quickfix/location list changedtick
3739func Xqftick_tests(cchar)
3740 call s:setup_commands(a:cchar)
3741
3742 call g:Xsetlist([], 'f')
3743
3744 Xexpr "F1:10:Line10"
3745 let qfid = g:Xgetlist({'id' : 0}).id
3746 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3747 Xaddexpr "F2:20:Line20\nF2:21:Line21"
3748 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3749 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3750 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3751 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3752 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3753 call g:Xsetlist([], 'a', {'title' : 'New Title'})
3754 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3755
3756 enew!
3757 call append(0, ["F5:50:L50", "F6:60:L60"])
3758 Xaddbuffer
3759 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3760 enew!
3761
3762 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3763 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3764 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3765 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3766 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3767 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3768 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3769 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3770 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3771 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3772 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3773
3774 call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3775 Xfile Xone
3776 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3777 Xaddfile Xone
3778 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3779
3780 " Test case for updating a non-current quickfix list
3781 call g:Xsetlist([], 'f')
3782 Xexpr "F1:1:L1"
3783 Xexpr "F2:2:L2"
3784 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3785 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3786 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3787
3788 call delete("Xone")
3789endfunc
3790
3791func Test_qf_tick()
3792 call Xqftick_tests('c')
3793 call Xqftick_tests('l')
3794endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01003795
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02003796" Test helpgrep with lang specifier
3797func Xtest_helpgrep_with_lang_specifier(cchar)
3798 call s:setup_commands(a:cchar)
3799 Xhelpgrep Vim@en
3800 call assert_equal('help', &filetype)
3801 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3802 new | only
3803endfunc
3804
3805func Test_helpgrep_with_lang_specifier()
3806 call Xtest_helpgrep_with_lang_specifier('c')
3807 call Xtest_helpgrep_with_lang_specifier('l')
3808endfunc
3809
Bram Moolenaar12237442017-12-19 12:38:52 +01003810" The following test used to crash Vim.
3811" Open the location list window and close the regular window associated with
3812" the location list. When the garbage collection runs now, it incorrectly
3813" marks the location list context as not in use and frees the context.
3814func Test_ll_window_ctx()
3815 call setloclist(0, [], 'f')
3816 call setloclist(0, [], 'a', {'context' : []})
3817 lopen | only
3818 call test_garbagecollect_now()
3819 echo getloclist(0, {'context' : 1}).context
3820 enew | only
3821endfunc
3822
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003823" The following test used to crash vim
3824func Test_lfile_crash()
3825 sp Xtest
3826 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02003827 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003828 au! QuickFixCmdPre
3829endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01003830
3831" The following test used to crash vim
3832func Test_lbuffer_crash()
3833 sv Xtest
3834 augroup QF_Test
3835 au!
3836 au * * bw
3837 augroup END
3838 lbuffer
3839 augroup QF_Test
3840 au!
3841 augroup END
3842endfunc
3843
3844" The following test used to crash vim
3845func Test_lexpr_crash()
3846 augroup QF_Test
3847 au!
3848 au * * call setloclist(0, [], 'f')
3849 augroup END
3850 lexpr ""
3851 augroup QF_Test
3852 au!
3853 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003854
Bram Moolenaar3c097222017-12-21 20:54:49 +01003855 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003856 augroup QF_Test
3857 au!
3858 au BufNew * call setloclist(0, [], 'f')
3859 augroup END
3860 lexpr 'x:1:x'
3861 augroup QF_Test
3862 au!
3863 augroup END
3864
3865 enew | only
3866 lexpr ''
3867 lopen
3868 augroup QF_Test
3869 au!
3870 au FileType * call setloclist(0, [], 'f')
3871 augroup END
3872 lexpr ''
3873 augroup QF_Test
3874 au!
3875 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01003876endfunc
3877
3878" The following test used to crash Vim
3879func Test_lvimgrep_crash()
3880 sv Xtest
3881 augroup QF_Test
3882 au!
3883 au * * call setloclist(0, [], 'f')
3884 augroup END
3885 lvimgrep quickfix test_quickfix.vim
3886 augroup QF_Test
3887 au!
3888 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003889
3890 new | only
3891 augroup QF_Test
3892 au!
3893 au BufEnter * call setloclist(0, [], 'r')
3894 augroup END
3895 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
3896 augroup QF_Test
3897 au!
3898 augroup END
3899
Bram Moolenaar3c097222017-12-21 20:54:49 +01003900 enew | only
3901endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01003902
Bram Moolenaar2573af32020-03-14 17:21:34 +01003903func Test_lvimgrep_crash2()
3904 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02003905 call assert_fails('lvimgrep x x', 'E471:')
3906 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01003907
3908 au! BufNewFile
3909endfunc
3910
Bram Moolenaarde046542017-12-26 13:53:11 +01003911" Test for the position of the quickfix and location list window
3912func Test_qfwin_pos()
3913 " Open two windows
3914 new | only
3915 new
3916 cexpr ['F1:10:L10']
3917 copen
3918 " Quickfix window should be the bottom most window
3919 call assert_equal(3, winnr())
3920 close
3921 " Open at the very top
3922 wincmd t
3923 topleft copen
3924 call assert_equal(1, winnr())
3925 close
3926 " open left of the current window
3927 wincmd t
3928 below new
3929 leftabove copen
3930 call assert_equal(2, winnr())
3931 close
3932 " open right of the current window
3933 rightbelow copen
3934 call assert_equal(3, winnr())
3935 close
3936endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02003937
3938" Tests for quickfix/location lists changed by autocommands when
3939" :vimgrep/:lvimgrep commands are running.
3940func Test_vimgrep_autocmd()
3941 call setqflist([], 'f')
3942 call writefile(['stars'], 'Xtest1.txt')
3943 call writefile(['stars'], 'Xtest2.txt')
3944
3945 " Test 1:
3946 " When searching for a pattern using :vimgrep, if the quickfix list is
3947 " changed by an autocmd, the results should be added to the correct quickfix
3948 " list.
3949 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
3950 silent vimgrep stars Xtest*.txt
3951 call assert_equal(1, getqflist({'nr' : 0}).nr)
3952 call assert_equal(3, getqflist({'nr' : '$'}).nr)
3953 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
3954 au! BufRead Xtest2.txt
3955
3956 " Test 2:
3957 " When searching for a pattern using :vimgrep, if the quickfix list is
3958 " freed, then a error should be given.
3959 silent! %bwipe!
3960 call setqflist([], 'f')
3961 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
3962 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
3963 au! BufRead Xtest2.txt
3964
3965 " Test 3:
3966 " When searching for a pattern using :lvimgrep, if the location list is
3967 " freed, then the command should error out.
3968 silent! %bwipe!
3969 let g:save_winid = win_getid()
3970 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
3971 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
3972 au! BufRead Xtest2.txt
3973
3974 call delete('Xtest1.txt')
3975 call delete('Xtest2.txt')
3976 call setqflist([], 'f')
3977endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02003978
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01003979" Test for an autocmd changing the current directory when running vimgrep
3980func Xvimgrep_autocmd_cd(cchar)
3981 call s:setup_commands(a:cchar)
3982
3983 %bwipe
3984 let save_cwd = getcwd()
3985
3986 augroup QF_Test
3987 au!
3988 autocmd BufRead * silent cd %:p:h
3989 augroup END
3990
3991 10Xvimgrep /vim/ Xdir/**
3992 let l = g:Xgetlist()
3993 call assert_equal('f1.txt', bufname(l[0].bufnr))
3994 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
3995
3996 augroup QF_Test
3997 au!
3998 augroup END
3999
4000 exe 'cd ' . save_cwd
4001endfunc
4002
4003func Test_vimgrep_autocmd_cd()
4004 call mkdir('Xdir/a', 'p')
4005 call mkdir('Xdir/b', 'p')
4006 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt')
4007 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt')
4008 call Xvimgrep_autocmd_cd('c')
4009 call Xvimgrep_autocmd_cd('l')
4010 %bwipe
4011 call delete('Xdir', 'rf')
4012endfunc
4013
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004014" The following test used to crash Vim
4015func Test_lhelpgrep_autocmd()
4016 lhelpgrep quickfix
4017 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4018 lhelpgrep buffer
4019 call assert_equal('help', &filetype)
4020 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4021 lhelpgrep tabpage
4022 call assert_equal('help', &filetype)
4023 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
4024 au! QuickFixCmdPost
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004025
4026 new | only
4027 augroup QF_Test
4028 au!
4029 au BufEnter * call setqflist([], 'f')
4030 augroup END
4031 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004032 " run the test with a help window already open
4033 help
4034 wincmd w
4035 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004036 augroup QF_Test
4037 au! BufEnter
4038 augroup END
4039
4040 new | only
4041 augroup QF_Test
4042 au!
4043 au BufEnter * call setqflist([], 'r')
4044 augroup END
4045 call assert_fails('helpgrep quickfix', 'E925:')
4046 augroup QF_Test
4047 au! BufEnter
4048 augroup END
4049
4050 new | only
4051 augroup QF_Test
4052 au!
4053 au BufEnter * call setloclist(0, [], 'r')
4054 augroup END
4055 call assert_fails('lhelpgrep quickfix', 'E926:')
4056 augroup QF_Test
4057 au! BufEnter
4058 augroup END
4059
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004060 new | only
4061endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004062
4063" Test for shortening/simplifying the file name when opening the
4064" quickfix window or when displaying the quickfix list
4065func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004066 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004067 %bwipe
4068 " Create a quickfix list with a absolute path filename
4069 let fname = getcwd() . '/test_quickfix.vim'
4070 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4071 call assert_equal(fname, bufname('test_quickfix.vim'))
4072 " Opening the quickfix window should simplify the file path
4073 cwindow
4074 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4075 cclose
4076 %bwipe
4077 " Create a quickfix list with a absolute path filename
4078 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4079 call assert_equal(fname, bufname('test_quickfix.vim'))
4080 " Displaying the quickfix list should simplify the file path
4081 silent! clist
4082 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004083 " Add a few entries for the same file with different paths and check whether
4084 " the buffer name is shortened
4085 %bwipe
4086 call setqflist([], 'f')
4087 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4088 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4089 \ {'filename' : fname, 'lnum' : 30}], ' ')
4090 copen
4091 call assert_equal(['test_quickfix.vim|10| ',
4092 \ 'test_quickfix.vim|20| ',
4093 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4094 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004095endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004096
4097" Quickfix title tests
4098" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4099" Otherwise due to indentation, the title is set with spaces at the beginning
4100" of the command.
4101func Test_qftitle()
4102 call writefile(["F1:1:Line1"], 'Xerr')
4103
4104 " :cexpr
4105 exe "cexpr readfile('Xerr')"
4106 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4107
4108 " :cgetexpr
4109 exe "cgetexpr readfile('Xerr')"
4110 call assert_equal(":cgetexpr readfile('Xerr')",
4111 \ getqflist({'title' : 1}).title)
4112
4113 " :caddexpr
4114 call setqflist([], 'f')
4115 exe "caddexpr readfile('Xerr')"
4116 call assert_equal(":caddexpr readfile('Xerr')",
4117 \ getqflist({'title' : 1}).title)
4118
4119 " :cbuffer
4120 new Xerr
4121 exe "cbuffer"
4122 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4123
4124 " :cgetbuffer
4125 edit Xerr
4126 exe "cgetbuffer"
4127 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4128
4129 " :caddbuffer
4130 call setqflist([], 'f')
4131 edit Xerr
4132 exe "caddbuffer"
4133 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4134
4135 " :cfile
4136 exe "cfile Xerr"
4137 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4138
4139 " :cgetfile
4140 exe "cgetfile Xerr"
4141 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4142
4143 " :caddfile
4144 call setqflist([], 'f')
4145 exe "caddfile Xerr"
4146 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4147
4148 " :grep
4149 set grepprg=internal
4150 exe "grep F1 Xerr"
4151 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4152
4153 " :grepadd
4154 call setqflist([], 'f')
4155 exe "grepadd F1 Xerr"
4156 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4157 set grepprg&vim
4158
4159 " :vimgrep
4160 exe "vimgrep F1 Xerr"
4161 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4162
4163 " :vimgrepadd
4164 call setqflist([], 'f')
4165 exe "vimgrepadd F1 Xerr"
4166 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4167
4168 call setqflist(['F1:10:L10'], ' ')
4169 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4170
4171 call setqflist([], 'f')
4172 call setqflist(['F1:10:L10'], 'a')
4173 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4174
4175 call setqflist([], 'f')
4176 call setqflist(['F1:10:L10'], 'r')
4177 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4178
4179 close
4180 call delete('Xerr')
4181
4182 call setqflist([], ' ', {'title' : 'Errors'})
4183 copen
4184 call assert_equal('Errors', w:quickfix_title)
4185 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4186 call assert_equal('Errors', w:quickfix_title)
4187 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004188
4189 " Switching to another quickfix list in one tab page should update the
4190 " quickfix window title and statusline in all the other tab pages also
4191 call setqflist([], 'f')
4192 %bw!
4193 cgetexpr ['file_one:1:1: error in the first quickfix list']
4194 call setqflist([], 'a', {'title': 'first quickfix list'})
4195 cgetexpr ['file_two:2:1: error in the second quickfix list']
4196 call setqflist([], 'a', {'title': 'second quickfix list'})
4197 copen
4198 wincmd t
4199 tabnew two
4200 copen
4201 wincmd t
4202 colder
4203 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4204 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4205 call assert_equal(1, tabpagewinnr(1))
4206 call assert_equal(1, tabpagewinnr(2))
4207 tabnew
4208 call setqflist([], 'a', {'title': 'new quickfix title'})
4209 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4210 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4211 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004212endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004213
4214func Test_lbuffer_with_bwipe()
4215 new
4216 new
4217 augroup nasty
4218 au * * bwipe
4219 augroup END
4220 lbuffer
4221 augroup nasty
4222 au!
4223 augroup END
4224endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004225
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004226" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4227" running
4228func Xexpr_acmd_freelist(cchar)
4229 call s:setup_commands(a:cchar)
4230
Bram Moolenaar0366c012018-06-18 20:52:13 +02004231 " This was using freed memory.
4232 augroup nasty
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004233 au * * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004234 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004235 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004236 augroup nasty
4237 au!
4238 augroup END
4239endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004240
4241func Test_cexpr_acmd_freelist()
4242 call Xexpr_acmd_freelist('c')
4243 call Xexpr_acmd_freelist('l')
4244endfunc
4245
4246" Test for commands that create a new quickfix/location list and jump to the
4247" first error automatically.
4248func Xjumpto_first_error_test(cchar)
4249 call s:setup_commands(a:cchar)
4250
4251 call s:create_test_file('Xtestfile1')
4252 call s:create_test_file('Xtestfile2')
4253 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4254
4255 " Test for cexpr/lexpr
4256 enew
4257 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004258 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004259 call assert_equal(2, line('.'))
4260
4261 " Test for cfile/lfile
4262 enew
4263 call writefile(l, 'Xerr')
4264 Xfile Xerr
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 cbuffer/lbuffer
4269 edit Xerr
4270 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004271 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004272 call assert_equal(2, line('.'))
4273
4274 call delete('Xerr')
4275 call delete('Xtestfile1')
4276 call delete('Xtestfile2')
4277endfunc
4278
4279func Test_jumpto_first_error()
4280 call Xjumpto_first_error_test('c')
4281 call Xjumpto_first_error_test('l')
4282endfunc
4283
4284" Test for a quickfix autocmd changing the quickfix/location list before
4285" jumping to the first error in the new list.
4286func Xautocmd_changelist(cchar)
4287 call s:setup_commands(a:cchar)
4288
4289 " Test for cfile/lfile
4290 call s:create_test_file('Xtestfile1')
4291 call s:create_test_file('Xtestfile2')
4292 Xexpr 'Xtestfile1:2:Line2'
4293 autocmd QuickFixCmdPost * Xolder
4294 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4295 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004296 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004297 call assert_equal(4, line('.'))
4298 autocmd! QuickFixCmdPost
4299
4300 " Test for cbuffer/lbuffer
4301 call g:Xsetlist([], 'f')
4302 Xexpr 'Xtestfile1:2:Line2'
4303 autocmd QuickFixCmdPost * Xolder
4304 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4305 edit Xerr
4306 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004307 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004308 call assert_equal(4, line('.'))
4309 autocmd! QuickFixCmdPost
4310
4311 " Test for cexpr/lexpr
4312 call g:Xsetlist([], 'f')
4313 Xexpr 'Xtestfile1:2:Line2'
4314 autocmd QuickFixCmdPost * Xolder
4315 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004316 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004317 call assert_equal(4, line('.'))
4318 autocmd! QuickFixCmdPost
4319
Bram Moolenaar851332e2018-07-03 19:16:00 +02004320 " The grepprg may not be set on non-Unix systems
4321 if has('unix')
4322 " Test for grep/lgrep
4323 call g:Xsetlist([], 'f')
4324 Xexpr 'Xtestfile1:2:Line2'
4325 autocmd QuickFixCmdPost * Xolder
4326 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004327 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004328 call assert_equal(5, line('.'))
4329 autocmd! QuickFixCmdPost
4330 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004331
4332 " Test for vimgrep/lvimgrep
4333 call g:Xsetlist([], 'f')
4334 Xexpr 'Xtestfile1:2:Line2'
4335 autocmd QuickFixCmdPost * Xolder
4336 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004337 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004338 call assert_equal(5, line('.'))
4339 autocmd! QuickFixCmdPost
4340
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004341 " Test for autocommands clearing the quickfix list before jumping to the
4342 " first error. This should not result in an error
4343 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4344 let v:errmsg = ''
4345 " Test for cfile/lfile
4346 Xfile Xerr
4347 call assert_true(v:errmsg !~# 'E42:')
4348 " Test for cbuffer/lbuffer
4349 edit Xerr
4350 Xbuffer
4351 call assert_true(v:errmsg !~# 'E42:')
4352 " Test for cexpr/lexpr
4353 Xexpr 'Xtestfile2:4:Line4'
4354 call assert_true(v:errmsg !~# 'E42:')
4355 " Test for grep/lgrep
4356 " The grepprg may not be set on non-Unix systems
4357 if has('unix')
4358 silent Xgrep Line5 Xtestfile2
4359 call assert_true(v:errmsg !~# 'E42:')
4360 endif
4361 " Test for vimgrep/lvimgrep
4362 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4363 autocmd! QuickFixCmdPost
4364
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004365 call delete('Xerr')
4366 call delete('Xtestfile1')
4367 call delete('Xtestfile2')
4368endfunc
4369
4370func Test_autocmd_changelist()
4371 call Xautocmd_changelist('c')
4372 call Xautocmd_changelist('l')
4373endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004374
4375" Tests for the ':filter /pat/ clist' command
4376func Test_filter_clist()
4377 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4378 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4379 \ split(execute('filter /Line 15/ clist'), "\n"))
4380 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4381 \ split(execute('filter /Xfile1/ clist'), "\n"))
4382 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4383
4384 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4385 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4386 call assert_equal([' 2 pqr:pat2: '],
4387 \ split(execute('filter /pqr/ clist'), "\n"))
4388 call assert_equal([' 1 abc:pat1: '],
4389 \ split(execute('filter /pat1/ clist'), "\n"))
4390endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004391
4392" Tests for the "CTRL-W <CR>" command.
4393func Xview_result_split_tests(cchar)
4394 call s:setup_commands(a:cchar)
4395
4396 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4397 call g:Xsetlist([])
4398 Xopen
4399 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004400 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004401 call assert_equal(l:win_count, winnr('$'))
4402 Xclose
4403endfunc
4404
4405func Test_view_result_split()
4406 call Xview_result_split_tests('c')
4407 call Xview_result_split_tests('l')
4408endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004409
4410" Test that :cc sets curswant
4411func Test_curswant()
4412 helpgrep quickfix
4413 normal! llll
4414 1cc
4415 call assert_equal(getcurpos()[4], virtcol('.'))
4416 cclose | helpclose
4417endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004418
4419" Test for opening a file from the quickfix window using CTRL-W <Enter>
4420" doesn't leave an empty buffer around.
4421func Test_splitview()
4422 call s:create_test_file('Xtestfile1')
4423 call s:create_test_file('Xtestfile2')
4424 new | only
4425 let last_bufnr = bufnr('Test_sv_1', 1)
4426 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4427 cgetexpr l
4428 copen
4429 let numbufs = len(getbufinfo())
4430 exe "normal \<C-W>\<CR>"
4431 copen
4432 exe "normal j\<C-W>\<CR>"
4433 " Make sure new empty buffers are not created
4434 call assert_equal(numbufs, len(getbufinfo()))
4435 " Creating a new buffer should use the next available buffer number
4436 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4437 bwipe Test_sv_1
4438 bwipe Test_sv_2
4439 new | only
4440
4441 " When split opening files from location list window, make sure that two
4442 " windows doesn't refer to the same location list
4443 lgetexpr l
4444 let locid = getloclist(0, {'id' : 0}).id
4445 lopen
4446 exe "normal \<C-W>\<CR>"
4447 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4448 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4449 new | only
4450
4451 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004452 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004453 lhelpgrep window
4454 let locid = getloclist(0, {'id' : 0}).id
4455 lwindow
4456 exe "normal j\<C-W>\<CR>"
4457 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4458 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4459 new | only
4460
Bram Moolenaar406cd902020-02-18 21:54:41 +01004461 " Using :split or :vsplit from a quickfix window should behave like a :new
4462 " or a :vnew command
4463 copen
4464 split
4465 call assert_equal(3, winnr('$'))
4466 let l = getwininfo()
4467 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4468 close
4469 copen
4470 vsplit
4471 let l = getwininfo()
4472 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4473 new | only
4474
Bram Moolenaarb2443732018-11-11 22:50:27 +01004475 call delete('Xtestfile1')
4476 call delete('Xtestfile2')
4477endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004478
4479" Test for parsing entries using visual screen column
4480func Test_viscol()
4481 enew
4482 call writefile(["Col1\tCol2\tCol3"], 'Xfile1')
4483 edit Xfile1
4484
4485 " Use byte offset for column number
4486 set efm&
4487 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4488 call assert_equal([5, 8], [col('.'), virtcol('.')])
4489 cnext
4490 call assert_equal([9, 12], [col('.'), virtcol('.')])
4491 cnext
4492 call assert_equal([14, 20], [col('.'), virtcol('.')])
4493
4494 " Use screen column offset for column number
4495 set efm=%f:%l:%v:%m
4496 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4497 call assert_equal([5, 8], [col('.'), virtcol('.')])
4498 cnext
4499 call assert_equal([9, 12], [col('.'), virtcol('.')])
4500 cnext
4501 call assert_equal([14, 20], [col('.'), virtcol('.')])
4502 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4503 call assert_equal([5, 8], [col('.'), virtcol('.')])
4504 cnext
4505 call assert_equal([10, 16], [col('.'), virtcol('.')])
4506 cnext
4507 call assert_equal([14, 20], [col('.'), virtcol('.')])
4508
4509 enew
4510 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4511
4512 " Use byte offset for column number
4513 set efm&
4514 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4515 call assert_equal([8, 10], [col('.'), virtcol('.')])
4516 cnext
4517 call assert_equal([11, 17], [col('.'), virtcol('.')])
4518 cnext
4519 call assert_equal([16, 25], [col('.'), virtcol('.')])
4520
4521 " Use screen column offset for column number
4522 set efm=%f:%l:%v:%m
4523 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4524 call assert_equal([8, 10], [col('.'), virtcol('.')])
4525 cnext
4526 call assert_equal([11, 17], [col('.'), virtcol('.')])
4527 cnext
4528 call assert_equal([16, 25], [col('.'), virtcol('.')])
4529
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004530 " Use screen column number with a multi-line error message
4531 enew
4532 call writefile(["à test"], 'Xfile1')
4533 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4534 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4535 call assert_equal('Xfile1', @%)
4536 call assert_equal([0, 1, 4, 0], getpos('.'))
4537
4538 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4539 " does not break this
4540 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4541 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4542 call assert_equal('Xfile1', @%)
4543 call assert_equal([0, 1, 3, 0], getpos('.'))
4544
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004545 enew | only
4546 set efm&
4547 call delete('Xfile1')
4548endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004549
4550" Test for the quickfix window buffer
4551func Xqfbuf_test(cchar)
4552 call s:setup_commands(a:cchar)
4553
4554 " Quickfix buffer should be reused across closing and opening a quickfix
4555 " window
4556 Xexpr "F1:10:Line10"
4557 Xopen
4558 let qfbnum = bufnr('')
4559 Xclose
4560 " Even after the quickfix window is closed, the buffer should be loaded
4561 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004562 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004563 Xopen
4564 " Buffer should be reused when opening the window again
4565 call assert_equal(qfbnum, bufnr(''))
4566 Xclose
4567
4568 if a:cchar == 'l'
4569 %bwipe
4570 " For a location list, when both the file window and the location list
4571 " window for the list are closed, then the buffer should be freed.
4572 new | only
4573 lexpr "F1:10:Line10"
4574 let wid = win_getid()
4575 lopen
4576 let qfbnum = bufnr('')
4577 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4578 close
4579 " When the location list window is closed, the buffer name should not
4580 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004581 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004582 call assert_true(bufloaded(qfbnum))
4583
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004584 " After deleting a location list buffer using ":bdelete", opening the
4585 " location list window should mark the buffer as a location list buffer.
4586 exe "bdelete " . qfbnum
4587 lopen
4588 call assert_equal("quickfix", &buftype)
4589 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
4590 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
4591 call assert_false(&swapfile)
4592 lclose
4593
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004594 " When the location list is cleared for the window, the buffer should be
4595 " removed
4596 call setloclist(0, [], 'f')
4597 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004598 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004599
4600 " When the location list is freed with the location list window open, the
4601 " location list buffer should not be lost. It should be reused when the
4602 " location list is again populated.
4603 lexpr "F1:10:Line10"
4604 lopen
4605 let wid = win_getid()
4606 let qfbnum = bufnr('')
4607 wincmd p
4608 call setloclist(0, [], 'f')
4609 lexpr "F1:10:Line10"
4610 lopen
4611 call assert_equal(wid, win_getid())
4612 call assert_equal(qfbnum, bufnr(''))
4613 lclose
4614
4615 " When the window with the location list is closed, the buffer should be
4616 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004617 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004618 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004619 endif
4620endfunc
4621
4622func Test_qfbuf()
4623 call Xqfbuf_test('c')
4624 call Xqfbuf_test('l')
4625endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004626
4627" If there is an autocmd to use only one window, then opening the location
4628" list window used to crash Vim.
4629func Test_winonly_autocmd()
4630 call s:create_test_file('Xtest1')
4631 " Autocmd to show only one Vim window at a time
4632 autocmd WinEnter * only
4633 new
4634 " Load the location list
4635 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
4636 let loclistid = getloclist(0, {'id' : 0}).id
4637 " Open the location list window. Only this window will be shown and the file
4638 " window is closed.
4639 lopen
4640 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4641 " Jump to an entry in the location list and make sure that the cursor is
4642 " positioned correctly.
4643 ll 3
4644 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004645 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004646 call assert_equal(15, line('.'))
4647 " Cleanup
4648 autocmd! WinEnter
4649 new | only
4650 call delete('Xtest1')
4651endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02004652
4653" Test to make sure that an empty quickfix buffer is not reused for loading
4654" a normal buffer.
4655func Test_empty_qfbuf()
4656 enew | only
4657 call writefile(["Test"], 'Xfile1')
4658 call setqflist([], 'f')
4659 copen | only
4660 let qfbuf = bufnr('')
4661 edit Xfile1
4662 call assert_notequal(qfbuf, bufnr(''))
4663 enew
4664 call delete('Xfile1')
4665endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004666
4667" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004668" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004669func Xtest_below(cchar)
4670 call s:setup_commands(a:cchar)
4671
4672 " No quickfix/location list
4673 call assert_fails('Xbelow', 'E42:')
4674 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004675 call assert_fails('Xbefore', 'E42:')
4676 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004677
4678 " Empty quickfix/location list
4679 call g:Xsetlist([])
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 call s:create_test_file('X1')
4686 call s:create_test_file('X2')
4687 call s:create_test_file('X3')
4688 call s:create_test_file('X4')
4689
4690 " Invalid entries
4691 edit X1
4692 call g:Xsetlist(["E1", "E2"])
4693 call assert_fails('Xbelow', 'E42:')
4694 call assert_fails('Xabove', 'E42:')
4695 call assert_fails('3Xbelow', 'E42:')
4696 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004697 call assert_fails('Xbefore', 'E42:')
4698 call assert_fails('Xafter', 'E42:')
4699 call assert_fails('3Xbefore', 'E42:')
4700 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004701
4702 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004703 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 +02004704 edit +7 X2
4705 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004706 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004707 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004708 normal 7G
4709 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004710 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004711 call assert_fails('Xbefore', 'E553:')
4712
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004713 normal 2j
4714 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004715 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004716 normal 7G
4717 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004718 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004719
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004720 " Last error in this file
4721 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004722 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004723 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004724 normal gg
4725 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004726 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004727 call assert_fails('Xafter', 'E553:')
4728
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004729 " First error in this file
4730 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004731 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004732 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004733 normal G
4734 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004735 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004736 call assert_fails('Xbefore', 'E553:')
4737
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004738 normal gg
4739 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004740 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004741 normal gg
4742 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004743 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004744
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004745 normal G
4746 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004747 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004748 normal G
4749 Xbefore 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 edit X4
4753 call assert_fails('Xabove', 'E42:')
4754 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004755 call assert_fails('Xbefore', 'E42:')
4756 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004757 if a:cchar == 'l'
4758 " If a buffer has location list entries from some other window but not
4759 " from the current window, then the commands should fail.
4760 edit X1 | split | call setloclist(0, [], 'f')
4761 call assert_fails('Xabove', 'E776:')
4762 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004763 call assert_fails('Xbefore', 'E776:')
4764 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004765 close
4766 endif
4767
4768 " Test for lines with multiple quickfix entries
4769 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3",
4770 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3",
4771 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
4772 edit +1 X2
4773 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004774 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004775 normal 1G
4776 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004777 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004778
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004779 normal gg
4780 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004781 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004782 normal gg
4783 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004784 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004785
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004786 normal G
4787 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004788 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004789 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004790 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004791 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004792
4793 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004794 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004795 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004796 normal G
4797 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004798 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004799
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004800 normal 10G
4801 Xabove
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 10G$
4804 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004805 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004806
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004807 normal 10G
4808 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004809 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004810 normal 9G
4811 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004812 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004813
4814 " Invalid range
4815 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02004816 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004817 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004818 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02004819 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004820 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004821 endif
4822
4823 call delete('X1')
4824 call delete('X2')
4825 call delete('X3')
4826 call delete('X4')
4827endfunc
4828
4829func Test_cbelow()
4830 call Xtest_below('c')
4831 call Xtest_below('l')
4832endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02004833
4834func Test_quickfix_count()
4835 let commands = [
4836 \ 'cNext',
4837 \ 'cNfile',
4838 \ 'cabove',
4839 \ 'cbelow',
4840 \ 'cfirst',
4841 \ 'clast',
4842 \ 'cnewer',
4843 \ 'cnext',
4844 \ 'cnfile',
4845 \ 'colder',
4846 \ 'cprevious',
4847 \ 'crewind',
4848 \
4849 \ 'lNext',
4850 \ 'lNfile',
4851 \ 'labove',
4852 \ 'lbelow',
4853 \ 'lfirst',
4854 \ 'llast',
4855 \ 'lnewer',
4856 \ 'lnext',
4857 \ 'lnfile',
4858 \ 'lolder',
4859 \ 'lprevious',
4860 \ 'lrewind',
4861 \ ]
4862 for cmd in commands
4863 call assert_fails('-1' .. cmd, 'E16:')
4864 call assert_fails('.' .. cmd, 'E16:')
4865 call assert_fails('%' .. cmd, 'E16:')
4866 call assert_fails('$' .. cmd, 'E16:')
4867 endfor
4868endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02004869
4870" Test for aborting quickfix commands using QuickFixCmdPre
4871func Xtest_qfcmd_abort(cchar)
4872 call s:setup_commands(a:cchar)
4873
4874 call g:Xsetlist([], 'f')
4875
4876 " cexpr/lexpr
4877 let e = ''
4878 try
4879 Xexpr ["F1:10:Line10", "F2:20:Line20"]
4880 catch /.*/
4881 let e = v:exception
4882 endtry
4883 call assert_equal('AbortCmd', e)
4884 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4885
4886 " cfile/lfile
4887 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1')
4888 let e = ''
4889 try
4890 Xfile Xfile1
4891 catch /.*/
4892 let e = v:exception
4893 endtry
4894 call assert_equal('AbortCmd', e)
4895 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4896 call delete('Xfile1')
4897
4898 " cgetbuffer/lgetbuffer
4899 enew!
4900 call append(0, ["F1:10:Line10", "F2:20:Line20"])
4901 let e = ''
4902 try
4903 Xgetbuffer
4904 catch /.*/
4905 let e = v:exception
4906 endtry
4907 call assert_equal('AbortCmd', e)
4908 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4909 enew!
4910
4911 " vimgrep/lvimgrep
4912 let e = ''
4913 try
4914 Xvimgrep /func/ test_quickfix.vim
4915 catch /.*/
4916 let e = v:exception
4917 endtry
4918 call assert_equal('AbortCmd', e)
4919 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4920
4921 " helpgrep/lhelpgrep
4922 let e = ''
4923 try
4924 Xhelpgrep quickfix
4925 catch /.*/
4926 let e = v:exception
4927 endtry
4928 call assert_equal('AbortCmd', e)
4929 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4930
4931 " grep/lgrep
4932 if has('unix')
4933 let e = ''
4934 try
4935 silent Xgrep func test_quickfix.vim
4936 catch /.*/
4937 let e = v:exception
4938 endtry
4939 call assert_equal('AbortCmd', e)
4940 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4941 endif
4942endfunc
4943
4944func Test_qfcmd_abort()
4945 augroup QF_Test
4946 au!
4947 autocmd QuickFixCmdPre * throw "AbortCmd"
4948 augroup END
4949
4950 call Xtest_qfcmd_abort('c')
4951 call Xtest_qfcmd_abort('l')
4952
4953 augroup QF_Test
4954 au!
4955 augroup END
4956endfunc
4957
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004958" Test for using a file in one of the parent directories.
4959func Test_search_in_dirstack()
4960 call mkdir('Xtestdir/a/b/c', 'p')
4961 let save_cwd = getcwd()
4962 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
4963 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
4964 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
4965 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
4966
4967 let lines = "Entering dir Xtestdir\n" .
4968 \ "Entering dir a\n" .
4969 \ "Entering dir b\n" .
4970 \ "Xfile2:2:X2_L2\n" .
4971 \ "Leaving dir a\n" .
4972 \ "Xfile1:2:X1_L2\n" .
4973 \ "Xfile3:1:X3_L1\n" .
4974 \ "Entering dir c\n" .
4975 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004976 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004977 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004978 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004979 call assert_equal(11, getqflist({'size' : 0}).size)
4980 call assert_equal(4, getqflist({'idx' : 0}).idx)
4981 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004982 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004983 cnext
4984 call assert_equal(6, getqflist({'idx' : 0}).idx)
4985 call assert_equal('X1_L2', getline('.'))
4986 cnext
4987 call assert_equal(7, getqflist({'idx' : 0}).idx)
4988 call assert_equal(1, line('$'))
4989 call assert_equal('', getline(1))
4990 cnext
4991 call assert_equal(9, getqflist({'idx' : 0}).idx)
4992 call assert_equal(1, line('$'))
4993 call assert_equal('', getline(1))
4994
4995 set efm&
4996 exe 'cd ' . save_cwd
4997 call delete('Xtestdir', 'rf')
4998endfunc
4999
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005000" Test for :cquit
5001func Test_cquit()
5002 " Exit Vim with a non-zero value
5003 if RunVim([], ["cquit 7"], '')
5004 call assert_equal(7, v:shell_error)
5005 endif
5006
5007 if RunVim([], ["50cquit"], '')
5008 call assert_equal(50, v:shell_error)
5009 endif
5010
5011 " Exit Vim with default value
5012 if RunVim([], ["cquit"], '')
5013 call assert_equal(1, v:shell_error)
5014 endif
5015
5016 " Exit Vim with zero value
5017 if RunVim([], ["cquit 0"], '')
5018 call assert_equal(0, v:shell_error)
5019 endif
5020
5021 " Exit Vim with negative value
5022 call assert_fails('-3cquit', 'E16:')
5023endfunc
5024
Bram Moolenaar858ba062020-05-31 23:11:59 +02005025" Test for getting a specific item from a quickfix list
5026func Xtest_getqflist_by_idx(cchar)
5027 call s:setup_commands(a:cchar)
5028 " Empty list
5029 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5030 Xexpr ['F1:10:L10', 'F1:20:L20']
5031 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5032 call assert_equal(bufnr('F1'), l[0].bufnr)
5033 call assert_equal(20, l[0].lnum)
5034 call assert_equal('L20', l[0].text)
5035 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5036 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
5037 %bwipe!
5038endfunc
5039
5040func Test_getqflist_by_idx()
5041 call Xtest_getqflist_by_idx('c')
5042 call Xtest_getqflist_by_idx('l')
5043endfunc
5044
5045" Test for the 'quickfixtextfunc' setting
5046func Tqfexpr(info)
5047 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005048 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005049 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005050 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005051 endif
5052
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005053 let l = []
5054 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5055 let e = qfl[idx]
5056 let s = ''
5057 if e.bufnr != 0
5058 let bname = bufname(e.bufnr)
5059 let s ..= fnamemodify(bname, ':.')
5060 endif
5061 let s ..= '-'
5062 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5063 let s ..= e.text
5064 call add(l, s)
5065 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005066
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005067 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005068endfunc
5069
5070func Xtest_qftextfunc(cchar)
5071 call s:setup_commands(a:cchar)
5072
5073 set efm=%f:%l:%c:%m
5074 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005075 call assert_equal('Tqfexpr', &quickfixtextfunc)
5076 call assert_equal('',
5077 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005078 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5079 Xwindow
5080 call assert_equal('F1-L10C2-green', getline(1))
5081 call assert_equal('F1-L20C4-blue', getline(2))
5082 Xclose
5083 set quickfixtextfunc&vim
5084 Xwindow
5085 call assert_equal('F1|10 col 2| green', getline(1))
5086 call assert_equal('F1|20 col 4| blue', getline(2))
5087 Xclose
5088 set efm&
5089 set quickfixtextfunc&
5090
5091 " Test for per list 'quickfixtextfunc' setting
5092 func PerQfText(info)
5093 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005094 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005095 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005096 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005097 endif
5098 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005099 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005100 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005101 let l = []
5102 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5103 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5104 endfor
5105 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005106 endfunc
5107 set quickfixtextfunc=Tqfexpr
5108 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5109 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5110 Xwindow
5111 call assert_equal('Line 10, Col 2', getline(1))
5112 call assert_equal('Line 20, Col 4', getline(2))
5113 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005114 call assert_equal(function('PerQfText'),
5115 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005116 " Add entries to the list when the quickfix buffer is hidden
5117 Xaddexpr ['F1:30:6:red']
5118 Xwindow
5119 call assert_equal('Line 30, Col 6', getline(3))
5120 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005121 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005122 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005123 set quickfixtextfunc&
5124 delfunc PerQfText
5125
5126 " Non-existing function
5127 set quickfixtextfunc=Tabc
5128 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5129 call assert_fails("Xwindow", 'E117:')
5130 Xclose
5131 set quickfixtextfunc&
5132
5133 " set option to a non-function
5134 set quickfixtextfunc=[10,\ 20]
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 function with different set of arguments
5141 func Xqftext(a, b, c)
5142 return a:a .. a:b .. a:c
5143 endfunc
5144 set quickfixtextfunc=Xqftext
5145 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5146 call assert_fails("Xwindow", 'E119:')
5147 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005148
5149 " set option to a function that returns a list with non-strings
5150 func Xqftext2(d)
5151 return ['one', [], 'two']
5152 endfunc
5153 set quickfixtextfunc=Xqftext2
5154 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5155 \ 'E730:')
5156 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005157 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5158 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005159 Xclose
5160
Bram Moolenaar858ba062020-05-31 23:11:59 +02005161 set quickfixtextfunc&
5162 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005163 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005164
5165 " set the global option to a lambda function
5166 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5167 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5168 Xwindow
5169 call assert_equal(['green', 'blue'], getline(1, '$'))
5170 Xclose
5171 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)
5172 set quickfixtextfunc&
5173
5174 " use a lambda function that returns an empty list
5175 set quickfixtextfunc={d\ ->\ []}
5176 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5177 Xwindow
5178 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5179 \ getline(1, '$'))
5180 Xclose
5181 set quickfixtextfunc&
5182
5183 " use a lambda function that returns a list with empty strings
5184 set quickfixtextfunc={d\ ->\ ['',\ '']}
5185 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5186 Xwindow
5187 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5188 \ getline(1, '$'))
5189 Xclose
5190 set quickfixtextfunc&
5191
5192 " set the per-quickfix list text function to a lambda function
5193 call g:Xsetlist([], ' ',
5194 \ {'quickfixtextfunc' :
5195 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5196 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5197 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5198 Xwindow
5199 call assert_equal('Line 10, Col 2', getline(1))
5200 call assert_equal('Line 20, Col 4', getline(2))
5201 Xclose
5202 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5203 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005204endfunc
5205
5206func Test_qftextfunc()
5207 call Xtest_qftextfunc('c')
5208 call Xtest_qftextfunc('l')
5209endfunc
5210
Bram Moolenaarec98e932020-06-08 19:35:59 +02005211" Running :lhelpgrep command more than once in a help window, doesn't jump to
5212" the help topic
5213func Test_lhelpgrep_from_help_window()
5214 call mkdir('Xtestdir/doc', 'p')
5215 call writefile(['window'], 'Xtestdir/doc/a.txt')
5216 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5217 let save_rtp = &rtp
5218 let &rtp = 'Xtestdir'
5219 lhelpgrep window
5220 lhelpgrep buffer
5221 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5222 lhelpgrep window
5223 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5224 let &rtp = save_rtp
5225 call delete('Xtestdir', 'rf')
5226 new | only!
5227endfunc
5228
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005229" Test for the crash fixed by 7.3.715
5230func Test_setloclist_crash()
5231 %bw!
5232 let g:BufNum = bufnr()
5233 augroup QF_Test
5234 au!
5235 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5236 augroup END
5237
5238 try
5239 lvimgrep /.*/ *.mak
5240 catch /E926:/
5241 endtry
5242 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5243 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5244
5245 augroup QF_Test
5246 au!
5247 augroup END
5248 unlet g:BufNum
5249 %bw!
5250endfunc
5251
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005252" Test for adding an invalid entry with the quickfix window open and making
5253" sure that the window contents are not changed
5254func Test_add_invalid_entry_with_qf_window()
5255 call setqflist([], 'f')
5256 cexpr "Xfile1:10:aa"
5257 copen
5258 call setqflist(['bb'], 'a')
5259 call assert_equal(1, line('$'))
5260 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
5261 call assert_equal([{'lnum': 10, 'bufnr': bufnr('Xfile1'), 'col': 0, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': 'aa'}], getqflist())
5262 cclose
5263endfunc
5264
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005265" Test for very weird problem: autocommand causes a failure, resulting opening
5266" the quickfix window to fail. This still splits the window, but otherwise
5267" should not mess up buffers.
5268func Test_quickfix_window_fails_to_open()
5269 CheckScreendump
5270
5271 let lines =<< trim END
5272 anything
5273 try
5274 anything
5275 endtry
5276 END
5277 call writefile(lines, 'XquickfixFails')
5278
5279 let lines =<< trim END
5280 split XquickfixFails
5281 silent vimgrep anything %
5282 normal o
5283 au BufLeave * ++once source XquickfixFails
5284 " This will trigger the autocommand, which causes an error, what follows
5285 " is aborted but the window was already split.
5286 silent! cwindow
5287 END
5288 call writefile(lines, 'XtestWinFails')
5289 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
5290 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
5291
5292 " clean up
5293 call term_sendkeys(buf, ":bwipe!\<CR>")
5294 call term_wait(buf)
5295 call StopVimInTerminal(buf)
5296 call delete('XtestWinFails')
5297 call delete('XquickfixFails')
5298endfunc
5299
Bram Moolenaar2d870f82020-12-05 13:41:01 +01005300" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01005301" is changed.
5302func Xqfbuf_update(cchar)
5303 call s:setup_commands(a:cchar)
5304
5305 Xexpr "F1:1:line1"
5306 Xopen
5307 call assert_equal(['F1|1| line1'], getline(1, '$'))
5308 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5309
5310 " Test setqflist() using the 'lines' key in 'what'
5311 " add a new entry
5312 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
5313 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
5314 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5315 " replace all the entries with a single entry
5316 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
5317 call assert_equal(['F3|3| line3'], getline(1, '$'))
5318 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5319 " remove all the entries
5320 call g:Xsetlist([], 'r', {'lines' : []})
5321 call assert_equal([''], getline(1, '$'))
5322 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5323 " add a new list
5324 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
5325 call assert_equal(['F4|4| line4'], getline(1, '$'))
5326 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5327
5328 " Test setqflist() using the 'items' key in 'what'
5329 " add a new entry
5330 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
5331 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
5332 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5333 " replace all the entries with a single entry
5334 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
5335 call assert_equal(['F6|6| line6'], getline(1, '$'))
5336 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5337 " remove all the entries
5338 call g:Xsetlist([], 'r', {'items' : []})
5339 call assert_equal([''], getline(1, '$'))
5340 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5341 " add a new list
5342 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
5343 call assert_equal(['F7|7| line7'], getline(1, '$'))
5344 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5345
5346 call g:Xsetlist([], ' ', {})
5347 call assert_equal([''], getline(1, '$'))
5348 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5349
5350 Xclose
5351endfunc
5352
5353func Test_qfbuf_update()
5354 call Xqfbuf_update('c')
5355 call Xqfbuf_update('l')
5356endfunc
5357
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005358" vim: shiftwidth=2 sts=2 expandtab