blob: 18b774c8b94e525b142b235099d20ef195bf3efe [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>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020035 command! -count=999 -nargs=* Xvimgrep <mods> <count>vimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010036 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>
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +020072 command! -count=999 -nargs=* Xvimgrep <mods> <count>lvimgrep <args>
Bram Moolenaarf9ae1542019-11-18 22:02:16 +010073 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')
Bram Moolenaar39f3b142021-02-14 12:57:36 +0100712 writefile(['vim9script'], dir .. '/ftplugin/qf.vim')
Bram Moolenaare5a2dc82021-01-03 19:52:05 +0100713 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 Moolenaar5f7d4c02021-05-05 21:31:39 +0200725def Test_vim9_cexpr()
726 var text = 'somefile:95:error'
727 cexpr text
728 var l = getqflist()
729 assert_equal(1, l->len())
730 assert_equal(95, l[0].lnum)
731 assert_equal('error', l[0].text)
732
733 text = 'somefile:77:warning'
734 caddexpr text
735 l = getqflist()
736 assert_equal(2, l->len())
737 assert_equal(77, l[1].lnum)
738 assert_equal('warning', l[1].text)
739enddef
740
Bram Moolenaar6920c722016-01-22 22:44:10 +0100741func Test_errortitle()
742 augroup QfBufWinEnter
743 au!
744 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
745 augroup END
746 copen
747 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'')'}]
748 call setqflist(a)
749 call assert_equal(':setqflist()', g:a)
750 augroup QfBufWinEnter
751 au!
752 augroup END
753 augroup! QfBufWinEnter
754endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100755
Bram Moolenaar5584df62016-03-18 21:00:51 +0100756func Test_vimgreptitle()
757 augroup QfBufWinEnter
758 au!
759 au BufWinEnter * :let g:a=get(w:, 'quickfix_title', 'NONE')
760 augroup END
761 try
762 vimgrep /pattern/j file
763 catch /E480/
764 endtry
765 copen
766 call assert_equal(': vimgrep /pattern/j file', g:a)
767 augroup QfBufWinEnter
768 au!
769 augroup END
770 augroup! QfBufWinEnter
771endfunc
772
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100773func XqfTitleTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200774 call s:setup_commands(a:cchar)
Bram Moolenaare27dba42016-03-15 14:11:10 +0100775
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200776 Xgetexpr ['file:1:1:message']
777 let l = g:Xgetlist()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100778 if a:cchar == 'c'
779 call setqflist(l, 'r')
780 else
781 call setloclist(0, l, 'r')
782 endif
783
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200784 Xopen
Bram Moolenaare27dba42016-03-15 14:11:10 +0100785 if a:cchar == 'c'
786 let title = ':setqflist()'
787 else
788 let title = ':setloclist()'
789 endif
790 call assert_equal(title, w:quickfix_title)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200791 Xclose
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100792endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100793
794" Tests for quickfix window's title
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100795func Test_qf_title()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +0200796 call XqfTitleTests('c')
797 call XqfTitleTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100798endfunc
Bram Moolenaare27dba42016-03-15 14:11:10 +0100799
800" Tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100801func Test_efm()
Bram Moolenaare27dba42016-03-15 14:11:10 +0100802 let save_efm = &efm
803 set efm=%EEEE%m,%WWWW%m,%+CCCC%.%#,%-GGGG%.%#
804 cgetexpr ['WWWW', 'EEEE', 'CCCC']
805 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
806 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
807 cgetexpr ['WWWW', 'GGGG', 'EEEE', 'CCCC']
808 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
809 call assert_equal("[['W', 1], ['E^@CCCC', 1]]", l)
810 cgetexpr ['WWWW', 'GGGG', 'ZZZZ', 'EEEE', 'CCCC', 'YYYY']
811 let l = strtrans(string(map(getqflist(), '[v:val.text, v:val.valid]')))
812 call assert_equal("[['W', 1], ['ZZZZ', 0], ['E^@CCCC', 1], ['YYYY', 0]]", l)
813 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100814endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100815
816" This will test for problems in quickfix:
817" A. incorrectly copying location lists which caused the location list to show
818" a different name than the file that was actually being displayed.
819" B. not reusing the window for which the location list window is opened but
820" instead creating new windows.
821" C. make sure that the location list window is not reused instead of the
822" window it belongs to.
823"
824" Set up the test environment:
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100825func ReadTestProtocol(name)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100826 let base = substitute(a:name, '\v^test://(.*)%(\.[^.]+)?', '\1', '')
827 let word = substitute(base, '\v(.*)\..*', '\1', '')
828
829 setl modifiable
830 setl noreadonly
831 setl noswapfile
832 setl bufhidden=delete
833 %del _
834 " For problem 2:
835 " 'buftype' has to be set to reproduce the constant opening of new windows
836 setl buftype=nofile
837
838 call setline(1, word)
839
840 setl nomodified
841 setl nomodifiable
842 setl readonly
843 exe 'doautocmd BufRead ' . substitute(a:name, '\v^test://(.*)', '\1', '')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100844endfunc
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100845
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100846func Test_locationlist()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200847 enew
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100848
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200849 augroup testgroup
850 au!
851 autocmd BufReadCmd test://* call ReadTestProtocol(expand("<amatch>"))
852 augroup END
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100853
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200854 let words = [ "foo", "bar", "baz", "quux", "shmoo", "spam", "eggs" ]
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100855
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200856 let qflist = []
857 for word in words
858 call add(qflist, {'filename': 'test://' . word . '.txt', 'text': 'file ' . word . '.txt', })
859 " NOTE: problem 1:
860 " intentionally not setting 'lnum' so that the quickfix entries are not
861 " valid
862 eval qflist->setloclist(0, ' ')
863 endfor
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100864
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200865 " Test A
866 lrewind
867 enew
868 lopen
869 4lnext
870 vert split
871 wincmd L
872 lopen
873 wincmd p
874 lnext
875 let fileName = expand("%")
876 wincmd p
877 let locationListFileName = substitute(getline(line('.')), '\([^|]*\)|.*', '\1', '')
878 let fileName = substitute(fileName, '\\', '/', 'g')
879 let locationListFileName = substitute(locationListFileName, '\\', '/', 'g')
880 call assert_equal("test://bar.txt", fileName)
881 call assert_equal("test://bar.txt", locationListFileName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100882
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200883 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100884
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200885 " Test B:
886 lrewind
887 lopen
888 2
889 exe "normal \<CR>"
890 wincmd p
891 3
892 exe "normal \<CR>"
893 wincmd p
894 4
895 exe "normal \<CR>"
896 call assert_equal(2, winnr('$'))
897 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100898
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200899 " Test C:
900 lrewind
901 lopen
902 " Let's move the location list window to the top to check whether it (the
903 " first window found) will be reused when we try to open new windows:
904 wincmd K
905 2
906 exe "normal \<CR>"
907 wincmd p
908 3
909 exe "normal \<CR>"
910 wincmd p
911 4
912 exe "normal \<CR>"
913 1wincmd w
914 call assert_equal('quickfix', &buftype)
915 2wincmd w
916 let bufferName = expand("%")
917 let bufferName = substitute(bufferName, '\\', '/', 'g')
918 call assert_equal('test://quux.txt', bufferName)
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100919
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200920 wincmd n | only
Bram Moolenaar1ff2b642016-03-17 22:07:02 +0100921
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200922 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100923endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100924
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100925func Test_locationlist_curwin_was_closed()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200926 augroup testgroup
927 au!
928 autocmd BufReadCmd test_curwin.txt call R(expand("<amatch>"))
929 augroup END
Bram Moolenaar0899d692016-03-19 13:35:03 +0100930
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200931 func! R(n)
932 quit
933 endfunc
Bram Moolenaar0899d692016-03-19 13:35:03 +0100934
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200935 new
936 let q = []
937 call add(q, {'filename': 'test_curwin.txt' })
938 call setloclist(0, q)
939 call assert_fails('lrewind', 'E924:')
Bram Moolenaar0899d692016-03-19 13:35:03 +0100940
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200941 augroup! testgroup
Bram Moolenaaree85df32017-03-19 14:19:50 +0100942endfunc
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100943
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100944func Test_locationlist_cross_tab_jump()
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200945 call writefile(['loclistfoo'], 'loclistfoo')
946 call writefile(['loclistbar'], 'loclistbar')
947 set switchbuf=usetab
948
949 edit loclistfoo
950 tabedit loclistbar
951 silent lgrep loclistfoo loclist*
952 call assert_equal(1, tabpagenr())
953
954 enew | only | tabonly
955 set switchbuf&vim
956 call delete('loclistfoo')
957 call delete('loclistbar')
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100958endfunc
Bram Moolenaar0a9046f2016-10-15 19:28:13 +0200959
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100960" More tests for 'errorformat'
Bram Moolenaar2b946c92016-11-12 18:14:44 +0100961func Test_efm1()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200962 " The 'errorformat' setting is different on non-Unix systems.
963 " This test works only on Unix-like systems.
964 CheckUnix
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100965
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200966 let l =<< trim [DATA]
967 "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
968 "Xtestfile", line 6 col 19; this is an error
969 gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
970 Xtestfile:9: parse error before `asd'
971 make: *** [vim] Error 1
972 in file "Xtestfile" linenr 10: there is an error
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100973
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200974 2 returned
975 "Xtestfile", line 11 col 1; this is an error
976 "Xtestfile", line 12 col 2; this is another error
977 "Xtestfile", line 14:10; this is an error in column 10
978 =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
979 "Xtestfile", linenr 16: yet another problem
980 Error in "Xtestfile" at line 17:
981 x should be a dot
982 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
983 ^
984 Error in "Xtestfile" at line 18:
985 x should be a dot
986 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
987 .............^
988 Error in "Xtestfile" at line 19:
989 x should be a dot
990 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
991 --------------^
992 Error in "Xtestfile" at line 20:
993 x should be a dot
994 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
995 ^
Bram Moolenaar7eba3d22016-03-19 22:54:09 +0100996
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200997 Does anyone know what is the problem and how to correction it?
998 "Xtestfile", line 21 col 9: What is the title of the quickfix window?
999 "Xtestfile", line 22 col 9: What is the title of the quickfix window?
1000 [DATA]
1001
1002 call writefile(l, 'Xerrorfile1')
1003 call writefile(l[:-2], 'Xerrorfile2')
1004
1005 let m =<< [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001006 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
1007 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
1008 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
1009 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
1010 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
1011 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
1012 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
1013 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
1014 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
1015 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
1016 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
1017 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
1018 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
1019 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
1020 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
1021 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
1022 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
1023 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
1024 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
1025 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
1026 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
1027[DATA]
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001028 call writefile(m, 'Xtestfile')
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001029
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001030 let save_efm = &efm
1031 set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m
1032 set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001033
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001034 exe 'cf Xerrorfile2'
1035 clast
1036 copen
1037 call assert_equal(':cf Xerrorfile2', w:quickfix_title)
1038 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001039
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001040 exe 'cf Xerrorfile1'
1041 call assert_equal([4, 12], [line('.'), col('.')])
1042 cn
1043 call assert_equal([6, 19], [line('.'), col('.')])
1044 cn
1045 call assert_equal([9, 2], [line('.'), col('.')])
1046 cn
1047 call assert_equal([10, 2], [line('.'), col('.')])
1048 cn
1049 call assert_equal([11, 1], [line('.'), col('.')])
1050 cn
1051 call assert_equal([12, 2], [line('.'), col('.')])
1052 cn
1053 call assert_equal([14, 10], [line('.'), col('.')])
1054 cn
1055 call assert_equal([15, 3, 10], [line('.'), col('.'), virtcol('.')])
1056 cn
1057 call assert_equal([16, 2], [line('.'), col('.')])
1058 cn
1059 call assert_equal([17, 6], [line('.'), col('.')])
1060 cn
1061 call assert_equal([18, 7], [line('.'), col('.')])
1062 cn
1063 call assert_equal([19, 8], [line('.'), col('.')])
1064 cn
1065 call assert_equal([20, 9], [line('.'), col('.')])
1066 clast
1067 cprev
1068 cprev
1069 wincmd w
1070 call assert_equal(':cf Xerrorfile1', w:quickfix_title)
1071 wincmd p
Bram Moolenaar7eba3d22016-03-19 22:54:09 +01001072
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001073 let &efm = save_efm
1074 call delete('Xerrorfile1')
1075 call delete('Xerrorfile2')
1076 call delete('Xtestfile')
Bram Moolenaaree85df32017-03-19 14:19:50 +01001077endfunc
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001078
Bram Moolenaarab47c612016-06-14 22:02:26 +02001079" Test for quickfix directory stack support
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001080func s:dir_stack_tests(cchar)
Bram Moolenaar38df43b2016-06-20 21:41:12 +02001081 call s:setup_commands(a:cchar)
1082
Bram Moolenaarab47c612016-06-14 22:02:26 +02001083 let save_efm=&efm
1084 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
1085
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001086 let lines = ["Entering dir 'dir1/a'",
1087 \ 'habits2.txt:1:Nine Healthy Habits',
1088 \ "Entering dir 'b'",
1089 \ 'habits3.txt:2:0 Hours of television',
1090 \ 'habits2.txt:7:5 Small meals',
1091 \ "Entering dir 'dir1/c'",
1092 \ 'habits4.txt:3:1 Hour of exercise',
1093 \ "Leaving dir 'dir1/c'",
1094 \ "Leaving dir 'dir1/a'",
1095 \ 'habits1.txt:4:2 Liters of water',
1096 \ "Entering dir 'dir2'",
1097 \ 'habits5.txt:5:3 Cups of hot green tea',
1098 \ "Leaving dir 'dir2'"
1099 \]
Bram Moolenaarab47c612016-06-14 22:02:26 +02001100
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001101 Xexpr ""
1102 for l in lines
1103 Xaddexpr l
1104 endfor
Bram Moolenaarab47c612016-06-14 22:02:26 +02001105
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001106 let qf = g:Xgetlist()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001107
1108 call assert_equal('dir1/a/habits2.txt', bufname(qf[1].bufnr))
1109 call assert_equal(1, qf[1].lnum)
1110 call assert_equal('dir1/a/b/habits3.txt', bufname(qf[3].bufnr))
1111 call assert_equal(2, qf[3].lnum)
1112 call assert_equal('dir1/a/habits2.txt', bufname(qf[4].bufnr))
1113 call assert_equal(7, qf[4].lnum)
1114 call assert_equal('dir1/c/habits4.txt', bufname(qf[6].bufnr))
1115 call assert_equal(3, qf[6].lnum)
1116 call assert_equal('habits1.txt', bufname(qf[9].bufnr))
1117 call assert_equal(4, qf[9].lnum)
1118 call assert_equal('dir2/habits5.txt', bufname(qf[11].bufnr))
1119 call assert_equal(5, qf[11].lnum)
1120
1121 let &efm=save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001122endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001123
1124" Tests for %D and %X errorformat options
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001125func Test_efm_dirstack()
Bram Moolenaarab47c612016-06-14 22:02:26 +02001126 " Create the directory stack and files
1127 call mkdir('dir1')
1128 call mkdir('dir1/a')
1129 call mkdir('dir1/a/b')
1130 call mkdir('dir1/c')
1131 call mkdir('dir2')
1132
1133 let lines = ["Nine Healthy Habits",
1134 \ "0 Hours of television",
1135 \ "1 Hour of exercise",
1136 \ "2 Liters of water",
1137 \ "3 Cups of hot green tea",
1138 \ "4 Short mental breaks",
1139 \ "5 Small meals",
1140 \ "6 AM wake up time",
1141 \ "7 Minutes of laughter",
1142 \ "8 Hours of sleep (at least)",
1143 \ "9 PM end of the day and off to bed"
1144 \ ]
1145 call writefile(lines, 'habits1.txt')
1146 call writefile(lines, 'dir1/a/habits2.txt')
1147 call writefile(lines, 'dir1/a/b/habits3.txt')
1148 call writefile(lines, 'dir1/c/habits4.txt')
1149 call writefile(lines, 'dir2/habits5.txt')
1150
1151 call s:dir_stack_tests('c')
1152 call s:dir_stack_tests('l')
1153
1154 call delete('dir1', 'rf')
1155 call delete('dir2', 'rf')
1156 call delete('habits1.txt')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001157endfunc
Bram Moolenaarab47c612016-06-14 22:02:26 +02001158
Bram Moolenaar9b457942016-10-09 16:10:05 +02001159" Test for resync after continuing an ignored message
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001160func Xefm_ignore_continuations(cchar)
Bram Moolenaar9b457942016-10-09 16:10:05 +02001161 call s:setup_commands(a:cchar)
1162
1163 let save_efm = &efm
1164
1165 let &efm =
1166 \ '%Eerror %m %l,' .
1167 \ '%-Wignored %m %l,' .
1168 \ '%+Cmore ignored %m %l,' .
1169 \ '%Zignored end'
1170 Xgetexpr ['ignored warning 1', 'more ignored continuation 2', 'ignored end', 'error resync 4']
1171 let l = map(g:Xgetlist(), '[v:val.text, v:val.valid, v:val.lnum, v:val.type]')
1172 call assert_equal([['resync', 1, 4, 'E']], l)
1173
1174 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001175endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001176
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001177func Test_efm_ignore_continuations()
Bram Moolenaar9b457942016-10-09 16:10:05 +02001178 call Xefm_ignore_continuations('c')
1179 call Xefm_ignore_continuations('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001180endfunc
Bram Moolenaar9b457942016-10-09 16:10:05 +02001181
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001182" Tests for invalid error format specifies
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001183func Xinvalid_efm_Tests(cchar)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001184 call s:setup_commands(a:cchar)
1185
Bram Moolenaar049cba92016-06-26 14:38:04 +02001186 let save_efm = &efm
1187
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001188 set efm=%f:%l:%m,%f:%f:%l:%m
1189 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E372:')
1190
1191 set efm=%f:%l:%m,%f:%l:%r:%m
1192 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1193
1194 set efm=%f:%l:%m,%O:%f:%l:%m
1195 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E373:')
1196
1197 set efm=%f:%l:%m,%f:%l:%*[^a-z
1198 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E374:')
1199
1200 set efm=%f:%l:%m,%f:%l:%*c
1201 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E375:')
1202
1203 set efm=%f:%l:%m,%L%M%N
1204 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E376:')
1205
1206 set efm=%f:%l:%m,%f:%l:%m:%R
1207 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E377:')
1208
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001209 " Invalid regular expression
1210 set efm=%\\%%k
1211 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E867:')
1212
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001213 set efm=
1214 call assert_fails('Xexpr "abc.txt:1:Hello world"', 'E378:')
1215
1216 set efm=%DEntering\ dir\ abc,%f:%l:%m
1217 call assert_fails('Xexpr ["Entering dir abc", "abc.txt:1:Hello world"]', 'E379:')
1218
1219 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001220endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001221
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001222func Test_invalid_efm()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001223 call Xinvalid_efm_Tests('c')
1224 call Xinvalid_efm_Tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001225endfunc
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001226
1227" TODO:
1228" Add tests for the following formats in 'errorformat'
1229" %r %O
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001230func Test_efm2()
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001231 let save_efm = &efm
Bram Moolenaar049cba92016-06-26 14:38:04 +02001232
1233 " Test for %s format in efm
1234 set efm=%f:%s
1235 cexpr 'Xtestfile:Line search text'
Bram Moolenaar049cba92016-06-26 14:38:04 +02001236 let l = getqflist()
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001237 call assert_equal('^\VLine search text\$', l[0].pattern)
1238 call assert_equal(0, l[0].lnum)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001239
Bram Moolenaaree85df32017-03-19 14:19:50 +01001240 let l = split(execute('clist', ''), "\n")
1241 call assert_equal([' 1 Xtestfile:^\VLine search text\$: '], l)
1242
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001243 " Test for a long line
1244 cexpr 'Xtestfile:' . repeat('a', 1026)
1245 let l = getqflist()
1246 call assert_equal('^\V' . repeat('a', 1019) . '\$', l[0].pattern)
1247
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001248 " Test for %P, %Q and %t format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001249 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001250 [Xtestfile1]
1251 (1,17) error: ';' missing
1252 (21,2) warning: variable 'z' not defined
1253 (67,3) error: end of file found before string ended
1254 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001255
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001256 [Xtestfile2]
1257 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001258
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001259 [Xtestfile3]
1260 NEW compiler v1.1
1261 (2,2) warning: variable 'x' not defined
1262 (67,3) warning: 's' already defined
1263 --
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001264 [DATA]
1265
Bram Moolenaaree85df32017-03-19 14:19:50 +01001266 set efm=%+P[%f]%r,(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%+Q--%r
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001267 " To exercise the push/pop file functionality in quickfix, the test files
1268 " need to be created.
1269 call writefile(['Line1'], 'Xtestfile1')
1270 call writefile(['Line2'], 'Xtestfile2')
1271 call writefile(['Line3'], 'Xtestfile3')
Bram Moolenaar361c8f02016-07-02 15:41:47 +02001272 cexpr ""
1273 for l in lines
1274 caddexpr l
1275 endfor
Bram Moolenaar049cba92016-06-26 14:38:04 +02001276 let l = getqflist()
Bram Moolenaaree85df32017-03-19 14:19:50 +01001277 call assert_equal(12, len(l))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001278 call assert_equal(21, l[2].lnum)
1279 call assert_equal(2, l[2].col)
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001280 call assert_equal('w', l[2].type)
1281 call assert_equal('e', l[3].type)
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001282 call delete('Xtestfile1')
1283 call delete('Xtestfile2')
1284 call delete('Xtestfile3')
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001285
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001286 " Test for %P, %Q with non-existing files
1287 cexpr lines
1288 let l = getqflist()
1289 call assert_equal(14, len(l))
1290 call assert_equal('[Xtestfile1]', l[0].text)
1291 call assert_equal('[Xtestfile2]', l[6].text)
1292 call assert_equal('[Xtestfile3]', l[9].text)
1293
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001294 " Tests for %E, %C and %Z format specifiers
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001295 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001296 Error 275
1297 line 42
1298 column 3
1299 ' ' expected after '--'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001300 [DATA]
1301
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001302 set efm=%EError\ %n,%Cline\ %l,%Ccolumn\ %c,%Z%m
1303 cgetexpr lines
1304 let l = getqflist()
1305 call assert_equal(275, l[0].nr)
1306 call assert_equal(42, l[0].lnum)
1307 call assert_equal(3, l[0].col)
1308 call assert_equal('E', l[0].type)
1309 call assert_equal("\n' ' expected after '--'", l[0].text)
1310
1311 " Test for %>
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001312 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001313 Error in line 147 of foo.c:
1314 unknown variable 'i'
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001315 [DATA]
1316
Bram Moolenaar0fcc7c62016-07-02 21:22:52 +02001317 set efm=unknown\ variable\ %m,%E%>Error\ in\ line\ %l\ of\ %f:,%Z%m
1318 cgetexpr lines
1319 let l = getqflist()
1320 call assert_equal(147, l[0].lnum)
1321 call assert_equal('E', l[0].type)
1322 call assert_equal("\nunknown variable 'i'", l[0].text)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001323
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001324 " Test for %A, %C and other formats
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001325 let lines =<< trim [DATA]
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001326 ==============================================================
1327 FAIL: testGetTypeIdCachesResult (dbfacadeTest.DjsDBFacadeTest)
1328 --------------------------------------------------------------
1329 Traceback (most recent call last):
1330 File "unittests/dbfacadeTest.py", line 89, in testFoo
1331 self.assertEquals(34, dtid)
1332 File "/usr/lib/python2.2/unittest.py", line 286, in
1333 failUnlessEqual
1334 raise self.failureException, \\
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001335 W:AssertionError: 34 != 33
Bram Moolenaare7eb9272019-06-24 00:58:07 +02001336
1337 --------------------------------------------------------------
1338 Ran 27 tests in 0.063s
Bram Moolenaarc79745a2019-05-20 22:12:34 +02001339 [DATA]
1340
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001341 set efm=%C\ %.%#,%A\ \ File\ \"%f\"\\,\ line\ %l%.%#,%Z%[%^\ ]%\\@=%t:%m
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001342 cgetexpr lines
1343 let l = getqflist()
1344 call assert_equal(8, len(l))
1345 call assert_equal(89, l[4].lnum)
1346 call assert_equal(1, l[4].valid)
1347 call assert_equal('unittests/dbfacadeTest.py', bufname(l[4].bufnr))
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001348 call assert_equal('W', l[4].type)
Bram Moolenaare87e6dd2016-07-17 19:25:04 +02001349
Bram Moolenaard76ce852018-05-01 15:02:04 +02001350 " Test for %o
1351 set efm=%f(%o):%l\ %m
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001352 cgetexpr ['Xotestfile(Language.PureScript.Types):20 Error']
1353 call writefile(['Line1'], 'Xotestfile')
Bram Moolenaard76ce852018-05-01 15:02:04 +02001354 let l = getqflist()
1355 call assert_equal(1, len(l), string(l))
1356 call assert_equal('Language.PureScript.Types', l[0].module)
1357 copen
1358 call assert_equal('Language.PureScript.Types|20| Error', getline(1))
1359 call feedkeys("\<CR>", 'xn')
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001360 call assert_equal('Xotestfile', expand('%:t'))
Bram Moolenaard76ce852018-05-01 15:02:04 +02001361 cclose
1362 bd
Bram Moolenaarbc7845d2018-05-01 16:26:48 +02001363 call delete("Xotestfile")
Bram Moolenaard76ce852018-05-01 15:02:04 +02001364
Bram Moolenaar70077dd2019-11-24 12:12:42 +01001365 " Test for a long module name
1366 cexpr 'Xtest(' . repeat('m', 1026) . '):15 message'
1367 let l = getqflist()
1368 call assert_equal(repeat('m', 1024), l[0].module)
1369 call assert_equal(15, l[0].lnum)
1370 call assert_equal('message', l[0].text)
1371
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001372 " The following sequence of commands used to crash Vim
1373 set efm=%W%m
1374 cgetexpr ['msg1']
1375 let l = getqflist()
1376 call assert_equal(1, len(l), string(l))
1377 call assert_equal('msg1', l[0].text)
1378 set efm=%C%m
1379 lexpr 'msg2'
1380 let l = getloclist(0)
1381 call assert_equal(1, len(l), string(l))
1382 call assert_equal('msg2', l[0].text)
1383 lopen
1384 call setqflist([], 'r')
1385 caddbuf
1386 let l = getqflist()
1387 call assert_equal(1, len(l), string(l))
1388 call assert_equal('|| msg2', l[0].text)
1389
Bram Moolenaar78ddc062018-05-15 21:56:34 +02001390 " When matching error lines, case should be ignored. Test for this.
1391 set noignorecase
1392 let l=getqflist({'lines' : ['Xtest:FOO10:Line 20'], 'efm':'%f:foo%l:%m'})
1393 call assert_equal(10, l.items[0].lnum)
1394 call assert_equal('Line 20', l.items[0].text)
1395 set ignorecase&
1396
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001397 new | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001398 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001399endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001400
Bram Moolenaare9283662020-06-07 14:10:47 +02001401" Test for '%t' (error type) field in 'efm'
1402func Test_efm_error_type()
1403 let save_efm = &efm
1404
1405 " error type
1406 set efm=%f:%l:%t:%m
1407 cexpr ["Xfile1:10:E:msg1", "Xfile1:20:W:msg2", "Xfile1:30:I:msg3",
1408 \ "Xfile1:40:N:msg4", "Xfile1:50:R:msg5"]
1409 let output = split(execute('clist'), "\n")
1410 call assert_equal([
1411 \ ' 1 Xfile1:10 error: msg1',
1412 \ ' 2 Xfile1:20 warning: msg2',
1413 \ ' 3 Xfile1:30 info: msg3',
1414 \ ' 4 Xfile1:40 note: msg4',
1415 \ ' 5 Xfile1:50 R: msg5'], output)
1416
1417 " error type and a error number
1418 set efm=%f:%l:%t:%n:%m
1419 cexpr ["Xfile1:10:E:2:msg1", "Xfile1:20:W:4:msg2", "Xfile1:30:I:6:msg3",
1420 \ "Xfile1:40:N:8:msg4", "Xfile1:50:R:3:msg5"]
1421 let output = split(execute('clist'), "\n")
1422 call assert_equal([
1423 \ ' 1 Xfile1:10 error 2: msg1',
1424 \ ' 2 Xfile1:20 warning 4: msg2',
1425 \ ' 3 Xfile1:30 info 6: msg3',
1426 \ ' 4 Xfile1:40 note 8: msg4',
1427 \ ' 5 Xfile1:50 R 3: msg5'], output)
1428 let &efm = save_efm
1429endfunc
1430
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001431func XquickfixChangedByAutocmd(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001432 call s:setup_commands(a:cchar)
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001433 if a:cchar == 'c'
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001434 let ErrorNr = 'E925'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001435 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001436 colder
1437 cgetexpr []
1438 endfunc
1439 else
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001440 let ErrorNr = 'E926'
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001441 func! ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001442 lolder
1443 lgetexpr []
1444 endfunc
1445 endif
1446
1447 augroup testgroup
1448 au!
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001449 autocmd BufReadCmd test_changed.txt call ReadFunc()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001450 augroup END
1451
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001452 new | only
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001453 let words = [ "a", "b" ]
1454 let qflist = []
1455 for word in words
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001456 call add(qflist, {'filename': 'test_changed.txt'})
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001457 call g:Xsetlist(qflist, ' ')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001458 endfor
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001459 call assert_fails('Xrewind', ErrorNr . ':')
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001460
1461 augroup! testgroup
1462endfunc
1463
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001464func Test_quickfix_was_changed_by_autocmd()
Bram Moolenaarffec3c52016-03-23 20:55:42 +01001465 call XquickfixChangedByAutocmd('c')
1466 call XquickfixChangedByAutocmd('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001467endfunc
Bram Moolenaar8b201792016-03-25 15:01:10 +01001468
Bram Moolenaar4d170af2020-09-13 22:21:22 +02001469func Test_setloclist_in_autocommand()
1470 call writefile(['test1', 'test2'], 'Xfile')
1471 edit Xfile
1472 let s:bufnr = bufnr()
1473 call setloclist(1,
1474 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1475 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}])
1476
1477 augroup Test_LocList
1478 au!
1479 autocmd BufEnter * call setloclist(1,
1480 \ [{'bufnr' : s:bufnr, 'lnum' : 1, 'text' : 'test1'},
1481 \ {'bufnr' : s:bufnr, 'lnum' : 2, 'text' : 'test2'}], 'r')
1482 augroup END
1483
1484 lopen
1485 call assert_fails('exe "normal j\<CR>"', 'E926:')
1486
1487 augroup Test_LocList
1488 au!
1489 augroup END
1490 call delete('Xfile')
1491endfunc
1492
Bram Moolenaar8b201792016-03-25 15:01:10 +01001493func Test_caddbuffer_to_empty()
1494 helpgr quickfix
1495 call setqflist([], 'r')
1496 cad
Bram Moolenaarf68f1d72016-03-25 17:14:06 +01001497 try
1498 cn
1499 catch
1500 " number of matches is unknown
1501 call assert_true(v:exception =~ 'E553:')
1502 endtry
Bram Moolenaar8b201792016-03-25 15:01:10 +01001503 quit!
1504endfunc
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001505
1506func Test_cgetexpr_works()
1507 " this must not crash Vim
1508 cgetexpr [$x]
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001509 lgetexpr [$x]
Bram Moolenaar89c64d52016-03-27 18:44:40 +02001510endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001511
1512" Tests for the setqflist() and setloclist() functions
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001513func SetXlistTests(cchar, bnum)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001514 call s:setup_commands(a:cchar)
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001515
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001516 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 1},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001517 \ {'bufnr': a:bnum, 'lnum': 2}])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001518 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001519 call assert_equal(2, len(l))
1520 call assert_equal(2, l[1].lnum)
1521
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001522 Xnext
1523 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3}], 'a')
1524 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001525 call assert_equal(3, len(l))
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001526 Xnext
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001527 call assert_equal(3, line('.'))
1528
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001529 " Appending entries to the list should not change the cursor position
1530 " in the quickfix window
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001531 Xwindow
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001532 1
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001533 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 4},
Bram Moolenaar2b2b8ae2016-05-24 19:59:51 +02001534 \ {'bufnr': a:bnum, 'lnum': 5}], 'a')
1535 call assert_equal(1, line('.'))
1536 close
1537
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001538 call g:Xsetlist([{'bufnr': a:bnum, 'lnum': 3},
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001539 \ {'bufnr': a:bnum, 'lnum': 4},
1540 \ {'bufnr': a:bnum, 'lnum': 5}], 'r')
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001541 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001542 call assert_equal(3, len(l))
1543 call assert_equal(5, l[2].lnum)
1544
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001545 call g:Xsetlist([])
1546 let l = g:Xgetlist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001547 call assert_equal(0, len(l))
Bram Moolenaaree85df32017-03-19 14:19:50 +01001548
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001549 " Tests for setting the 'valid' flag
1550 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':4, 'valid':0}])
1551 Xwindow
1552 call assert_equal(1, winnr('$'))
1553 let l = g:Xgetlist()
1554 call g:Xsetlist(l)
1555 call assert_equal(0, g:Xgetlist()[0].valid)
Bram Moolenaar9752c722018-12-22 16:49:34 +01001556 " Adding a non-valid entry should not mark the list as having valid entries
1557 call g:Xsetlist([{'bufnr':a:bnum, 'lnum':5, 'valid':0}], 'a')
1558 Xwindow
1559 call assert_equal(1, winnr('$'))
1560
1561 " :cnext/:cprev should still work even with invalid entries in the list
1562 let l = [{'bufnr' : a:bnum, 'lnum' : 1, 'text' : '1', 'valid' : 0},
1563 \ {'bufnr' : a:bnum, 'lnum' : 2, 'text' : '2', 'valid' : 0}]
1564 call g:Xsetlist(l)
1565 Xnext
1566 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1567 Xprev
1568 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1569 " :cnext/:cprev should still work after appending invalid entries to an
1570 " empty list
1571 call g:Xsetlist([])
1572 call g:Xsetlist(l, 'a')
1573 Xnext
1574 call assert_equal(2, g:Xgetlist({'idx' : 0}).idx)
1575 Xprev
1576 call assert_equal(1, g:Xgetlist({'idx' : 0}).idx)
1577
Bram Moolenaarf1d21c82017-04-22 21:20:46 +02001578 call g:Xsetlist([{'text':'Text1', 'valid':1}])
1579 Xwindow
1580 call assert_equal(2, winnr('$'))
1581 Xclose
1582 let save_efm = &efm
1583 set efm=%m
1584 Xgetexpr 'TestMessage'
1585 let l = g:Xgetlist()
1586 call g:Xsetlist(l)
1587 call assert_equal(1, g:Xgetlist()[0].valid)
1588 let &efm = save_efm
1589
Bram Moolenaaree85df32017-03-19 14:19:50 +01001590 " Error cases:
1591 " Refer to a non-existing buffer and pass a non-dictionary type
1592 call assert_fails("call g:Xsetlist([{'bufnr':998, 'lnum':4}," .
1593 \ " {'bufnr':999, 'lnum':5}])", 'E92:')
1594 call g:Xsetlist([[1, 2,3]])
1595 call assert_equal(0, len(g:Xgetlist()))
Bram Moolenaar99fa7212020-04-26 15:59:55 +02001596 call assert_fails('call g:Xsetlist([], [])', 'E928:')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001597endfunc
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001598
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001599func Test_setqflist()
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001600 new Xtestfile | only
1601 let bnum = bufnr('%')
1602 call setline(1, range(1,5))
1603
1604 call SetXlistTests('c', bnum)
1605 call SetXlistTests('l', bnum)
1606
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001607 enew!
Bram Moolenaarc1808d52016-04-18 20:04:00 +02001608 call delete('Xtestfile')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001609endfunc
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001610
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001611func Xlist_empty_middle(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001612 call s:setup_commands(a:cchar)
1613
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001614 " create three quickfix lists
Bram Moolenaaree85df32017-03-19 14:19:50 +01001615 let @/ = 'Test_'
1616 Xvimgrep // test_quickfix.vim
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001617 let testlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001618 call assert_true(testlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001619 Xvimgrep empty test_quickfix.vim
1620 call assert_true(len(g:Xgetlist()) > 0)
1621 Xvimgrep matches test_quickfix.vim
1622 let matchlen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001623 call assert_true(matchlen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001624 Xolder
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001625 " make the middle list empty
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001626 call g:Xsetlist([], 'r')
1627 call assert_true(len(g:Xgetlist()) == 0)
1628 Xolder
1629 call assert_equal(testlen, len(g:Xgetlist()))
1630 Xnewer
1631 Xnewer
1632 call assert_equal(matchlen, len(g:Xgetlist()))
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001633endfunc
1634
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001635func Test_setqflist_empty_middle()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001636 call Xlist_empty_middle('c')
1637 call Xlist_empty_middle('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001638endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001639
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001640func Xlist_empty_older(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001641 call s:setup_commands(a:cchar)
1642
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001643 " create three quickfix lists
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001644 Xvimgrep one test_quickfix.vim
1645 let onelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001646 call assert_true(onelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001647 Xvimgrep two test_quickfix.vim
1648 let twolen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001649 call assert_true(twolen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001650 Xvimgrep three test_quickfix.vim
1651 let threelen = len(g:Xgetlist())
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001652 call assert_true(threelen > 0)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001653 Xolder 2
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001654 " make the first list empty, check the others didn't change
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001655 call g:Xsetlist([], 'r')
1656 call assert_true(len(g:Xgetlist()) == 0)
1657 Xnewer
1658 call assert_equal(twolen, len(g:Xgetlist()))
1659 Xnewer
1660 call assert_equal(threelen, len(g:Xgetlist()))
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001661endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001662
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001663func Test_setqflist_empty_older()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001664 call Xlist_empty_older('c')
1665 call Xlist_empty_older('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001666endfunc
Bram Moolenaar1cee6932016-06-09 22:17:22 +02001667
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001668func XquickfixSetListWithAct(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001669 call s:setup_commands(a:cchar)
1670
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001671 let list1 = [{'filename': 'fnameA', 'text': 'A'},
1672 \ {'filename': 'fnameB', 'text': 'B'}]
1673 let list2 = [{'filename': 'fnameC', 'text': 'C'},
1674 \ {'filename': 'fnameD', 'text': 'D'},
1675 \ {'filename': 'fnameE', 'text': 'E'}]
1676
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01001677 " {action} is unspecified. Same as specifying ' '.
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001678 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 ' '.
1694 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001695 silent! Xnewer 99
1696 call g:Xsetlist(list1)
1697 call g:Xsetlist(list2, ' ')
1698 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001699 call assert_equal(3, len(li))
1700 call assert_equal('C', li[0]['text'])
1701 call assert_equal('D', li[1]['text'])
1702 call assert_equal('E', li[2]['text'])
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001703 silent! Xolder
1704 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001705 call assert_equal(2, len(li))
1706 call assert_equal('A', li[0]['text'])
1707 call assert_equal('B', li[1]['text'])
1708
1709 " {action} is specified 'a'.
1710 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001711 silent! Xnewer 99
1712 call g:Xsetlist(list1)
1713 call g:Xsetlist(list2, 'a')
1714 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001715 call assert_equal(5, len(li))
1716 call assert_equal('A', li[0]['text'])
1717 call assert_equal('B', li[1]['text'])
1718 call assert_equal('C', li[2]['text'])
1719 call assert_equal('D', li[3]['text'])
1720 call assert_equal('E', li[4]['text'])
1721
1722 " {action} is specified 'r'.
1723 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001724 silent! Xnewer 99
1725 call g:Xsetlist(list1)
1726 call g:Xsetlist(list2, 'r')
1727 let li = g:Xgetlist()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001728 call assert_equal(3, len(li))
1729 call assert_equal('C', li[0]['text'])
1730 call assert_equal('D', li[1]['text'])
1731 call assert_equal('E', li[2]['text'])
1732
1733 " Test for wrong value.
1734 new | only
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001735 call assert_fails("call g:Xsetlist(0)", 'E714:')
1736 call assert_fails("call g:Xsetlist(list1, '')", 'E927:')
1737 call assert_fails("call g:Xsetlist(list1, 'aa')", 'E927:')
1738 call assert_fails("call g:Xsetlist(list1, ' a')", 'E927:')
1739 call assert_fails("call g:Xsetlist(list1, 0)", 'E928:')
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001740endfunc
1741
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001742func Test_setqflist_invalid_nr()
1743 " The following command used to crash Vim
Bram Moolenaaraad222c2019-09-06 22:46:09 +02001744 eval []->setqflist(' ', {'nr' : $XXX_DOES_NOT_EXIST})
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01001745endfunc
1746
Bram Moolenaar99234f22020-02-10 22:56:54 +01001747func Test_setqflist_user_sets_buftype()
1748 call setqflist([{'text': 'foo'}, {'text': 'bar'}])
1749 set buftype=quickfix
1750 call setqflist([], 'a')
1751 enew
1752endfunc
1753
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001754func Test_quickfix_set_list_with_act()
Bram Moolenaard106e5b2016-04-21 19:38:07 +02001755 call XquickfixSetListWithAct('c')
1756 call XquickfixSetListWithAct('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001757endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001758
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001759func XLongLinesTests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001760 let l = g:Xgetlist()
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001761
Bram Moolenaar049cba92016-06-26 14:38:04 +02001762 call assert_equal(4, len(l))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001763 call assert_equal(1, l[0].lnum)
1764 call assert_equal(1, l[0].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001765 call assert_equal(1975, len(l[0].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001766 call assert_equal(2, l[1].lnum)
1767 call assert_equal(1, l[1].col)
1768 call assert_equal(4070, len(l[1].text))
1769 call assert_equal(3, l[2].lnum)
1770 call assert_equal(1, l[2].col)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001771 call assert_equal(4070, len(l[2].text))
1772 call assert_equal(4, l[3].lnum)
1773 call assert_equal(1, l[3].col)
1774 call assert_equal(10, len(l[3].text))
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001775
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001776 call g:Xsetlist([], 'r')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001777endfunc
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001778
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001779func s:long_lines_tests(cchar)
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001780 call s:setup_commands(a:cchar)
1781
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001782 let testfile = 'samples/quickfix.txt'
1783
1784 " file
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001785 exe 'Xgetfile' testfile
1786 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001787
1788 " list
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001789 Xexpr readfile(testfile)
1790 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001791
1792 " string
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001793 Xexpr join(readfile(testfile), "\n")
1794 call XLongLinesTests(a:cchar)
Bram Moolenaar6be8c8e2016-04-30 13:17:09 +02001795
1796 " buffer
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001797 exe 'edit' testfile
1798 exe 'Xbuffer' bufnr('%')
Bram Moolenaarf50df392016-06-21 21:33:34 +02001799 call XLongLinesTests(a:cchar)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001800endfunc
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001801
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001802func Test_long_lines()
Bram Moolenaar3ef5bf72016-06-15 22:41:31 +02001803 call s:long_lines_tests('c')
1804 call s:long_lines_tests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001805endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001806
Bram Moolenaar59941cb2020-09-05 17:03:40 +02001807func Test_cgetfile_on_long_lines()
1808 " Problematic values if the line is longer than 4096 bytes. Then 1024 bytes
1809 " are read at a time.
1810 for len in [4078, 4079, 4080, 5102, 5103, 5104, 6126, 6127, 6128, 7150, 7151, 7152]
1811 let lines = [
1812 \ '/tmp/file1:1:1:aaa',
1813 \ '/tmp/file2:1:1:%s',
1814 \ '/tmp/file3:1:1:bbb',
1815 \ '/tmp/file4:1:1:ccc',
1816 \ ]
1817 let lines[1] = substitute(lines[1], '%s', repeat('x', len), '')
1818 call writefile(lines, 'Xcqetfile.txt')
1819 cgetfile Xcqetfile.txt
1820 call assert_equal(4, getqflist(#{size: v:true}).size, 'with length ' .. len)
1821 endfor
1822 call delete('Xcqetfile.txt')
1823endfunc
1824
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001825func s:create_test_file(filename)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001826 let l = []
1827 for i in range(1, 20)
1828 call add(l, 'Line' . i)
1829 endfor
1830 call writefile(l, a:filename)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001831endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001832
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001833func Test_switchbuf()
Bram Moolenaar049cba92016-06-26 14:38:04 +02001834 call s:create_test_file('Xqftestfile1')
1835 call s:create_test_file('Xqftestfile2')
1836 call s:create_test_file('Xqftestfile3')
1837
1838 new | only
1839 edit Xqftestfile1
1840 let file1_winid = win_getid()
1841 new Xqftestfile2
1842 let file2_winid = win_getid()
1843 cgetexpr ['Xqftestfile1:5:Line5',
1844 \ 'Xqftestfile1:6:Line6',
1845 \ 'Xqftestfile2:10:Line10',
1846 \ 'Xqftestfile2:11:Line11',
1847 \ 'Xqftestfile3:15:Line15',
1848 \ 'Xqftestfile3:16:Line16']
1849
1850 new
1851 let winid = win_getid()
1852 cfirst | cnext
1853 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001854 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001855 call assert_equal(winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001856 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001857 call assert_equal(winid, win_getid())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001858
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001859 " Test for 'switchbuf' set to search for files in windows in the current
1860 " tabpage and jump to an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001861 set switchbuf=useopen
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001862 enew
Bram Moolenaar049cba92016-06-26 14:38:04 +02001863 cfirst | cnext
1864 call assert_equal(file1_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001865 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001866 call assert_equal(file2_winid, win_getid())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001867 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001868 call assert_equal(file2_winid, win_getid())
1869
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001870 " Test for 'switchbuf' set to search for files in tabpages and jump to an
1871 " existing tabpage (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001872 enew | only
1873 set switchbuf=usetab
1874 tabedit Xqftestfile1
1875 tabedit Xqftestfile2
Bram Moolenaar74240d32017-12-10 15:26:15 +01001876 tabedit Xqftestfile3
Bram Moolenaar049cba92016-06-26 14:38:04 +02001877 tabfirst
1878 cfirst | cnext
1879 call assert_equal(2, tabpagenr())
Bram Moolenaar99895ea2017-04-20 22:44:47 +02001880 2cnext
Bram Moolenaar049cba92016-06-26 14:38:04 +02001881 call assert_equal(3, tabpagenr())
Bram Moolenaar74240d32017-12-10 15:26:15 +01001882 6cnext
1883 call assert_equal(4, tabpagenr())
1884 2cpfile
1885 call assert_equal(2, tabpagenr())
1886 2cnfile
1887 call assert_equal(4, tabpagenr())
Bram Moolenaar049cba92016-06-26 14:38:04 +02001888 tabfirst | tabonly | enew
1889
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001890 " Test for 'switchbuf' set to open a new window for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001891 set switchbuf=split
1892 cfirst | cnext
1893 call assert_equal(1, winnr('$'))
1894 cnext | cnext
1895 call assert_equal(2, winnr('$'))
1896 cnext | cnext
1897 call assert_equal(3, winnr('$'))
Bram Moolenaar049cba92016-06-26 14:38:04 +02001898
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001899 " Test for 'switchbuf' set to open a new tabpage for every file
Bram Moolenaar049cba92016-06-26 14:38:04 +02001900 set switchbuf=newtab
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001901 enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001902 cfirst | cnext
1903 call assert_equal(1, tabpagenr('$'))
1904 cnext | cnext
1905 call assert_equal(2, tabpagenr('$'))
1906 cnext | cnext
1907 call assert_equal(3, tabpagenr('$'))
1908 tabfirst | enew | tabonly | only
1909
Bram Moolenaar539aa6b2019-11-17 18:09:38 +01001910 set switchbuf=uselast
1911 split
1912 let last_winid = win_getid()
1913 copen
1914 exe "normal 1G\<CR>"
1915 call assert_equal(last_winid, win_getid())
1916 enew | only
1917
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001918 " With an empty 'switchbuf', jumping to a quickfix entry should open the
1919 " file in an existing window (if present)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001920 set switchbuf=
1921 edit Xqftestfile1
1922 let file1_winid = win_getid()
1923 new Xqftestfile2
1924 let file2_winid = win_getid()
1925 copen
1926 exe "normal 1G\<CR>"
1927 call assert_equal(file1_winid, win_getid())
1928 copen
1929 exe "normal 3G\<CR>"
1930 call assert_equal(file2_winid, win_getid())
1931 copen | only
1932 exe "normal 5G\<CR>"
1933 call assert_equal(2, winnr('$'))
1934 call assert_equal(1, bufwinnr('Xqftestfile3'))
1935
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001936 " If only quickfix window is open in the current tabpage, jumping to an
Bram Moolenaar1bc353b2019-09-01 14:45:28 +02001937 " entry with 'switchbuf' set to 'usetab' should search in other tabpages.
Bram Moolenaar049cba92016-06-26 14:38:04 +02001938 enew | only
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001939 set switchbuf=usetab
1940 tabedit Xqftestfile1
1941 tabedit Xqftestfile2
1942 tabedit Xqftestfile3
1943 tabfirst
1944 copen | only
1945 clast
1946 call assert_equal(4, tabpagenr())
1947 tabfirst | tabonly | enew | only
Bram Moolenaar049cba92016-06-26 14:38:04 +02001948
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001949 " Jumping to a file that is not present in any of the tabpages and the
1950 " current tabpage doesn't have any usable windows, should open it in a new
1951 " window in the current tabpage.
1952 copen | only
1953 cfirst
1954 call assert_equal(1, tabpagenr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02001955 call assert_equal('Xqftestfile1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001956
1957 " If opening a file changes 'switchbuf', then the new value should be
1958 " retained.
Bram Moolenaar41d42992020-05-03 16:29:50 +02001959 set modeline&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01001960 call writefile(["vim: switchbuf=split"], 'Xqftestfile1')
1961 enew | only
1962 set switchbuf&vim
1963 cexpr "Xqftestfile1:1:10"
1964 call assert_equal('split', &switchbuf)
1965 call writefile(["vim: switchbuf=usetab"], 'Xqftestfile1')
1966 enew | only
1967 set switchbuf=useopen
1968 cexpr "Xqftestfile1:1:10"
1969 call assert_equal('usetab', &switchbuf)
1970 call writefile(["vim: switchbuf&vim"], 'Xqftestfile1')
1971 enew | only
1972 set switchbuf=useopen
1973 cexpr "Xqftestfile1:1:10"
1974 call assert_equal('', &switchbuf)
1975
Bram Moolenaar049cba92016-06-26 14:38:04 +02001976 call delete('Xqftestfile1')
1977 call delete('Xqftestfile2')
1978 call delete('Xqftestfile3')
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01001979 set switchbuf&vim
1980
1981 enew | only
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001982endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02001983
Bram Moolenaar2b946c92016-11-12 18:14:44 +01001984func Xadjust_qflnum(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02001985 call s:setup_commands(a:cchar)
1986
1987 enew | only
1988
Bram Moolenaarc1542742016-07-20 21:44:37 +02001989 let fname = 'Xqftestfile' . a:cchar
1990 call s:create_test_file(fname)
1991 exe 'edit ' . fname
Bram Moolenaar049cba92016-06-26 14:38:04 +02001992
Bram Moolenaarc1542742016-07-20 21:44:37 +02001993 Xgetexpr [fname . ':5:Line5',
1994 \ fname . ':10:Line10',
1995 \ fname . ':15:Line15',
1996 \ fname . ':20:Line20']
Bram Moolenaar049cba92016-06-26 14:38:04 +02001997
1998 6,14delete
1999 call append(6, ['Buffer', 'Window'])
2000
2001 let l = g:Xgetlist()
Bram Moolenaar049cba92016-06-26 14:38:04 +02002002 call assert_equal(5, l[0].lnum)
2003 call assert_equal(6, l[2].lnum)
2004 call assert_equal(13, l[3].lnum)
2005
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002006 " If a file doesn't have any quickfix entries, then deleting lines in the
2007 " file should not update the quickfix list
2008 call g:Xsetlist([], 'f')
2009 1,2delete
2010 call assert_equal([], g:Xgetlist())
2011
Bram Moolenaar049cba92016-06-26 14:38:04 +02002012 enew!
Bram Moolenaarc1542742016-07-20 21:44:37 +02002013 call delete(fname)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002014endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002015
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002016func Test_adjust_lnum()
Bram Moolenaarc1542742016-07-20 21:44:37 +02002017 call setloclist(0, [])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002018 call Xadjust_qflnum('c')
Bram Moolenaarc1542742016-07-20 21:44:37 +02002019 call setqflist([])
Bram Moolenaar049cba92016-06-26 14:38:04 +02002020 call Xadjust_qflnum('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002021endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002022
2023" Tests for the :grep/:lgrep and :grepadd/:lgrepadd commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002024func s:test_xgrep(cchar)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002025 call s:setup_commands(a:cchar)
2026
2027 " The following lines are used for the grep test. Don't remove.
2028 " Grep_Test_Text: Match 1
2029 " Grep_Test_Text: Match 2
2030 " GrepAdd_Test_Text: Match 1
2031 " GrepAdd_Test_Text: Match 2
2032 enew! | only
2033 set makeef&vim
2034 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002035 call assert_true(len(g:Xgetlist()) == 5)
Bram Moolenaar049cba92016-06-26 14:38:04 +02002036 Xopen
2037 call assert_true(w:quickfix_title =~ '^:grep')
2038 Xclose
2039 enew
2040 set makeef=Temp_File_##
2041 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002042 call assert_true(len(g:Xgetlist()) == 9)
2043
2044 " Try with 'grepprg' set to 'internal'
2045 set grepprg=internal
2046 silent Xgrep Grep_Test_Text: test_quickfix.vim
2047 silent Xgrepadd GrepAdd_Test_Text: test_quickfix.vim
2048 call assert_true(len(g:Xgetlist()) == 9)
2049 set grepprg&vim
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002050
2051 call writefile(['Vim'], 'XtestTempFile')
2052 set makeef=XtestTempFile
2053 silent Xgrep Grep_Test_Text: test_quickfix.vim
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002054 call assert_equal(5, len(g:Xgetlist()))
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002055 call assert_false(filereadable('XtestTempFile'))
2056 set makeef&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002057endfunc
Bram Moolenaar049cba92016-06-26 14:38:04 +02002058
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002059func Test_grep()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002060 " The grepprg may not be set on non-Unix systems
2061 CheckUnix
Bram Moolenaar049cba92016-06-26 14:38:04 +02002062
2063 call s:test_xgrep('c')
2064 call s:test_xgrep('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002065endfunc
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002066
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002067func Test_two_windows()
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002068 " Use one 'errorformat' for two windows. Add an expression to each of them,
2069 " make sure they each keep their own state.
2070 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
2071 call mkdir('Xone/a', 'p')
2072 call mkdir('Xtwo/a', 'p')
2073 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
2074 call writefile(lines, 'Xone/a/one.txt')
2075 call writefile(lines, 'Xtwo/a/two.txt')
2076
2077 new one
2078 let one_id = win_getid()
2079 lexpr ""
2080 new two
2081 let two_id = win_getid()
2082 lexpr ""
2083
2084 laddexpr "Entering dir 'Xtwo/a'"
2085 call win_gotoid(one_id)
2086 laddexpr "Entering dir 'Xone/a'"
2087 call win_gotoid(two_id)
2088 laddexpr 'two.txt:5:two two two'
2089 call win_gotoid(one_id)
2090 laddexpr 'one.txt:3:one one one'
2091
2092 let loc_one = getloclist(one_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002093 call assert_equal('Xone/a/one.txt', bufname(loc_one[1].bufnr))
2094 call assert_equal(3, loc_one[1].lnum)
2095
2096 let loc_two = getloclist(two_id)
Bram Moolenaar361c8f02016-07-02 15:41:47 +02002097 call assert_equal('Xtwo/a/two.txt', bufname(loc_two[1].bufnr))
2098 call assert_equal(5, loc_two[1].lnum)
2099
2100 call win_gotoid(one_id)
2101 bwipe!
2102 call win_gotoid(two_id)
2103 bwipe!
2104 call delete('Xone', 'rf')
2105 call delete('Xtwo', 'rf')
2106endfunc
Bram Moolenaardcb17002016-07-07 18:58:59 +02002107
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002108func XbottomTests(cchar)
Bram Moolenaar537ef082016-07-09 17:56:19 +02002109 call s:setup_commands(a:cchar)
2110
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002111 " Calling lbottom without any errors should fail
2112 if a:cchar == 'l'
2113 call assert_fails('lbottom', 'E776:')
2114 endif
2115
Bram Moolenaar875feea2017-06-11 16:07:51 +02002116 call g:Xsetlist([{'filename': 'foo', 'lnum': 42}])
Bram Moolenaar537ef082016-07-09 17:56:19 +02002117 Xopen
Bram Moolenaardcb17002016-07-07 18:58:59 +02002118 let wid = win_getid()
2119 call assert_equal(1, line('.'))
2120 wincmd w
Bram Moolenaar875feea2017-06-11 16:07:51 +02002121 call g:Xsetlist([{'filename': 'var', 'lnum': 24}], 'a')
Bram Moolenaar537ef082016-07-09 17:56:19 +02002122 Xbottom
Bram Moolenaardcb17002016-07-07 18:58:59 +02002123 call win_gotoid(wid)
2124 call assert_equal(2, line('.'))
Bram Moolenaar537ef082016-07-09 17:56:19 +02002125 Xclose
Bram Moolenaardcb17002016-07-07 18:58:59 +02002126endfunc
Bram Moolenaar537ef082016-07-09 17:56:19 +02002127
2128" Tests for the :cbottom and :lbottom commands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002129func Test_cbottom()
Bram Moolenaar537ef082016-07-09 17:56:19 +02002130 call XbottomTests('c')
2131 call XbottomTests('l')
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002132endfunc
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002133
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002134func HistoryTest(cchar)
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002135 call s:setup_commands(a:cchar)
2136
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002137 " clear all lists after the first one, then replace the first one.
2138 call g:Xsetlist([])
Bram Moolenaarb6fa30c2017-03-29 14:19:25 +02002139 call assert_fails('Xolder 99', 'E380:')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002140 let entry = {'filename': 'foo', 'lnum': 42}
2141 call g:Xsetlist([entry], 'r')
2142 call g:Xsetlist([entry, entry])
2143 call g:Xsetlist([entry, entry, entry])
2144 let res = split(execute(a:cchar . 'hist'), "\n")
2145 call assert_equal(3, len(res))
2146 let common = 'errors :set' . (a:cchar == 'c' ? 'qf' : 'loc') . 'list()'
2147 call assert_equal(' error list 1 of 3; 1 ' . common, res[0])
2148 call assert_equal(' error list 2 of 3; 2 ' . common, res[1])
2149 call assert_equal('> error list 3 of 3; 3 ' . common, res[2])
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002150
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002151 " Test for changing the quickfix lists
2152 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2153 exe '1' . a:cchar . 'hist'
2154 call assert_equal(1, g:Xgetlist({'nr' : 0}).nr)
2155 exe '3' . a:cchar . 'hist'
2156 call assert_equal(3, g:Xgetlist({'nr' : 0}).nr)
2157 call assert_fails('-2' . a:cchar . 'hist', 'E16:')
2158 call assert_fails('4' . a:cchar . 'hist', 'E16:')
2159
Bram Moolenaarb4d5fba2017-09-11 19:31:28 +02002160 call g:Xsetlist([], 'f')
2161 let l = split(execute(a:cchar . 'hist'), "\n")
2162 call assert_equal('No entries', l[0])
Bram Moolenaar8ffc7c82019-05-05 21:00:26 +02002163 if a:cchar == 'c'
2164 call assert_fails('4chist', 'E16:')
2165 else
2166 call assert_fails('4lhist', 'E776:')
2167 endif
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002168
2169 " An empty list should still show the stack history
2170 call g:Xsetlist([])
2171 let res = split(execute(a:cchar . 'hist'), "\n")
2172 call assert_equal('> error list 1 of 1; 0 ' . common, res[0])
2173
2174 call g:Xsetlist([], 'f')
Bram Moolenaarf6acffb2016-07-16 16:54:24 +02002175endfunc
2176
2177func Test_history()
2178 call HistoryTest('c')
2179 call HistoryTest('l')
2180endfunc
Bram Moolenaar015102e2016-07-16 18:24:56 +02002181
2182func Test_duplicate_buf()
2183 " make sure we can get the highest buffer number
2184 edit DoesNotExist
2185 edit DoesNotExist2
2186 let last_buffer = bufnr("$")
2187
2188 " make sure only one buffer is created
2189 call writefile(['this one', 'that one'], 'Xgrepthis')
2190 vimgrep one Xgrepthis
2191 vimgrep one Xgrepthis
2192 call assert_equal(last_buffer + 1, bufnr("$"))
2193
2194 call delete('Xgrepthis')
2195endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002196
2197" Quickfix/Location list set/get properties tests
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002198func Xproperty_tests(cchar)
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002199 call s:setup_commands(a:cchar)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002200
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002201 " Error cases
2202 call assert_fails('call g:Xgetlist(99)', 'E715:')
2203 call assert_fails('call g:Xsetlist(99)', 'E714:')
2204 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaard823fa92016-08-12 16:29:27 +02002205
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002206 " Set and get the title
2207 call g:Xsetlist([])
2208 Xopen
2209 wincmd p
2210 call g:Xsetlist([{'filename':'foo', 'lnum':27}])
2211 let s = g:Xsetlist([], 'a', {'title' : 'Sample'})
2212 call assert_equal(0, s)
2213 let d = g:Xgetlist({"title":1})
2214 call assert_equal('Sample', d.title)
2215 " Try setting title to a non-string value
2216 call assert_equal(-1, g:Xsetlist([], 'a', {'title' : ['Test']}))
2217 call assert_equal('Sample', g:Xgetlist({"title":1}).title)
2218
2219 Xopen
2220 call assert_equal('Sample', w:quickfix_title)
2221 Xclose
2222
2223 " Tests for action argument
2224 silent! Xolder 999
2225 let qfnr = g:Xgetlist({'all':1}).nr
2226 call g:Xsetlist([], 'r', {'title' : 'N1'})
2227 call assert_equal('N1', g:Xgetlist({'all':1}).title)
2228 call g:Xsetlist([], ' ', {'title' : 'N2'})
2229 call assert_equal(qfnr + 1, g:Xgetlist({'all':1}).nr)
2230
2231 let res = g:Xgetlist({'nr': 0})
2232 call assert_equal(qfnr + 1, res.nr)
2233 call assert_equal(['nr'], keys(res))
2234
2235 call g:Xsetlist([], ' ', {'title' : 'N3'})
2236 call assert_equal('N2', g:Xgetlist({'nr':2, 'title':1}).title)
2237
2238 " Changing the title of an earlier quickfix list
2239 call g:Xsetlist([], 'r', {'title' : 'NewTitle', 'nr' : 2})
2240 call assert_equal('NewTitle', g:Xgetlist({'nr':2, 'title':1}).title)
2241
2242 " Changing the title of an invalid quickfix list
2243 call assert_equal(-1, g:Xsetlist([], ' ',
2244 \ {'title' : 'SomeTitle', 'nr' : 99}))
2245 call assert_equal(-1, g:Xsetlist([], ' ',
2246 \ {'title' : 'SomeTitle', 'nr' : 'abc'}))
2247
2248 if a:cchar == 'c'
2249 copen
2250 call assert_equal({'winid':win_getid()}, getqflist({'winid':1}))
2251 cclose
2252 endif
2253
2254 " Invalid arguments
Bram Moolenaare2e40752020-09-04 21:18:46 +02002255 call assert_fails('call g:Xgetlist([])', 'E715:')
2256 call assert_fails('call g:Xsetlist([], "a", [])', 'E715:')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002257 let s = g:Xsetlist([], 'a', {'abc':1})
2258 call assert_equal(-1, s)
2259
2260 call assert_equal({}, g:Xgetlist({'abc':1}))
2261 call assert_equal('', g:Xgetlist({'nr':99, 'title':1}).title)
2262 call assert_equal('', g:Xgetlist({'nr':[], 'title':1}).title)
2263
2264 if a:cchar == 'l'
2265 call assert_equal({}, getloclist(99, {'title': 1}))
2266 endif
2267
2268 " Context related tests
2269 let s = g:Xsetlist([], 'a', {'context':[1,2,3]})
2270 call assert_equal(0, s)
2271 call test_garbagecollect_now()
2272 let d = g:Xgetlist({'context':1})
2273 call assert_equal([1,2,3], d.context)
2274 call g:Xsetlist([], 'a', {'context':{'color':'green'}})
2275 let d = g:Xgetlist({'context':1})
2276 call assert_equal({'color':'green'}, d.context)
2277 call g:Xsetlist([], 'a', {'context':"Context info"})
2278 let d = g:Xgetlist({'context':1})
2279 call assert_equal("Context info", d.context)
2280 call g:Xsetlist([], 'a', {'context':246})
2281 let d = g:Xgetlist({'context':1})
2282 call assert_equal(246, d.context)
2283 " set other Vim data types as context
2284 call g:Xsetlist([], 'a', {'context' : test_null_blob()})
2285 if has('channel')
2286 call g:Xsetlist([], 'a', {'context' : test_null_channel()})
2287 endif
2288 if has('job')
2289 call g:Xsetlist([], 'a', {'context' : test_null_job()})
2290 endif
2291 call g:Xsetlist([], 'a', {'context' : test_null_function()})
2292 call g:Xsetlist([], 'a', {'context' : test_null_partial()})
2293 call g:Xsetlist([], 'a', {'context' : ''})
2294 call test_garbagecollect_now()
2295 if a:cchar == 'l'
2296 " Test for copying context across two different location lists
2297 new | only
2298 let w1_id = win_getid()
2299 let l = [1]
2300 call setloclist(0, [], 'a', {'context':l})
2301 new
2302 let w2_id = win_getid()
2303 call add(l, 2)
2304 call assert_equal([1, 2], getloclist(w1_id, {'context':1}).context)
2305 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2306 unlet! l
2307 call assert_equal([1, 2], getloclist(w2_id, {'context':1}).context)
2308 only
2309 call setloclist(0, [], 'f')
2310 call assert_equal('', getloclist(0, {'context':1}).context)
2311 endif
2312
2313 " Test for changing the context of previous quickfix lists
2314 call g:Xsetlist([], 'f')
2315 Xexpr "One"
2316 Xexpr "Two"
2317 Xexpr "Three"
2318 call g:Xsetlist([], 'r', {'context' : [1], 'nr' : 1})
2319 call g:Xsetlist([], 'a', {'context' : [2], 'nr' : 2})
2320 " Also, check for setting the context using quickfix list number zero.
2321 call g:Xsetlist([], 'r', {'context' : [3], 'nr' : 0})
2322 call test_garbagecollect_now()
2323 let l = g:Xgetlist({'nr' : 1, 'context' : 1})
2324 call assert_equal([1], l.context)
2325 let l = g:Xgetlist({'nr' : 2, 'context' : 1})
2326 call assert_equal([2], l.context)
2327 let l = g:Xgetlist({'nr' : 3, 'context' : 1})
2328 call assert_equal([3], l.context)
2329
2330 " Test for changing the context through reference and for garbage
2331 " collection of quickfix context
2332 let l = ["red"]
2333 call g:Xsetlist([], ' ', {'context' : l})
2334 call add(l, "blue")
2335 let x = g:Xgetlist({'context' : 1})
2336 call add(x.context, "green")
2337 call assert_equal(["red", "blue", "green"], l)
2338 call assert_equal(["red", "blue", "green"], x.context)
2339 unlet l
2340 call test_garbagecollect_now()
2341 let m = g:Xgetlist({'context' : 1})
2342 call assert_equal(["red", "blue", "green"], m.context)
2343
2344 " Test for setting/getting items
2345 Xexpr ""
2346 let qfprev = g:Xgetlist({'nr':0})
2347 let s = g:Xsetlist([], ' ', {'title':'Green',
2348 \ 'items' : [{'filename':'F1', 'lnum':10}]})
2349 call assert_equal(0, s)
2350 let qfcur = g:Xgetlist({'nr':0})
2351 call assert_true(qfcur.nr == qfprev.nr + 1)
2352 let l = g:Xgetlist({'items':1})
2353 call assert_equal('F1', bufname(l.items[0].bufnr))
2354 call assert_equal(10, l.items[0].lnum)
2355 call g:Xsetlist([], 'a', {'items' : [{'filename':'F2', 'lnum':20},
2356 \ {'filename':'F2', 'lnum':30}]})
2357 let l = g:Xgetlist({'items':1})
2358 call assert_equal('F2', bufname(l.items[2].bufnr))
2359 call assert_equal(30, l.items[2].lnum)
2360 call g:Xsetlist([], 'r', {'items' : [{'filename':'F3', 'lnum':40}]})
2361 let l = g:Xgetlist({'items':1})
2362 call assert_equal('F3', bufname(l.items[0].bufnr))
2363 call assert_equal(40, l.items[0].lnum)
2364 call g:Xsetlist([], 'r', {'items' : []})
2365 let l = g:Xgetlist({'items':1})
2366 call assert_equal(0, len(l.items))
2367
2368 call g:Xsetlist([], 'r', {'title' : 'TestTitle'})
2369 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2370 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F1', 'lnum' : 10, 'text' : 'L10'}]})
2371 call assert_equal('TestTitle', g:Xgetlist({'title' : 1}).title)
2372
2373 " Test for getting id of window associated with a location list window
2374 if a:cchar == 'l'
2375 only
2376 call assert_equal(0, g:Xgetlist({'all' : 1}).filewinid)
2377 let wid = win_getid()
Bram Moolenaard823fa92016-08-12 16:29:27 +02002378 Xopen
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002379 call assert_equal(wid, g:Xgetlist({'filewinid' : 1}).filewinid)
2380 wincmd w
2381 call assert_equal(0, g:Xgetlist({'filewinid' : 1}).filewinid)
2382 only
2383 endif
Bram Moolenaard823fa92016-08-12 16:29:27 +02002384
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002385 " The following used to crash Vim with address sanitizer
2386 call g:Xsetlist([], 'f')
2387 call g:Xsetlist([], 'a', {'items' : [{'filename':'F1', 'lnum':10}]})
2388 call assert_equal(10, g:Xgetlist({'items':1}).items[0].lnum)
Bram Moolenaard823fa92016-08-12 16:29:27 +02002389
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002390 " Try setting the items using a string
2391 call assert_equal(-1, g:Xsetlist([], ' ', {'items' : 'Test'}))
Bram Moolenaar890680c2016-09-27 21:28:56 +02002392
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002393 " Save and restore the quickfix stack
2394 call g:Xsetlist([], 'f')
2395 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
2396 Xexpr "File1:10:Line1"
2397 Xexpr "File2:20:Line2"
2398 Xexpr "File3:30:Line3"
2399 let last_qf = g:Xgetlist({'nr':'$'}).nr
2400 call assert_equal(3, last_qf)
2401 let qstack = []
2402 for i in range(1, last_qf)
2403 let qstack = add(qstack, g:Xgetlist({'nr':i, 'all':1}))
2404 endfor
2405 call g:Xsetlist([], 'f')
2406 for i in range(len(qstack))
2407 call g:Xsetlist([], ' ', qstack[i])
2408 endfor
2409 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
2410 call assert_equal(10, g:Xgetlist({'nr':1, 'items':1}).items[0].lnum)
2411 call assert_equal(20, g:Xgetlist({'nr':2, 'items':1}).items[0].lnum)
2412 call assert_equal(30, g:Xgetlist({'nr':3, 'items':1}).items[0].lnum)
2413 call g:Xsetlist([], 'f')
Bram Moolenaar890680c2016-09-27 21:28:56 +02002414
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002415 " Swap two quickfix lists
2416 Xexpr "File1:10:Line10"
2417 Xexpr "File2:20:Line20"
2418 Xexpr "File3:30:Line30"
2419 call g:Xsetlist([], 'r', {'nr':1,'title':'Colors','context':['Colors']})
2420 call g:Xsetlist([], 'r', {'nr':2,'title':'Fruits','context':['Fruits']})
2421 let l1=g:Xgetlist({'nr':1,'all':1})
2422 let l2=g:Xgetlist({'nr':2,'all':1})
2423 let save_id = l1.id
2424 let l1.id=l2.id
2425 let l2.id=save_id
2426 call g:Xsetlist([], 'r', l1)
2427 call g:Xsetlist([], 'r', l2)
2428 let newl1=g:Xgetlist({'nr':1,'all':1})
2429 let newl2=g:Xgetlist({'nr':2,'all':1})
2430 call assert_equal('Fruits', newl1.title)
2431 call assert_equal(['Fruits'], newl1.context)
2432 call assert_equal('Line20', newl1.items[0].text)
2433 call assert_equal('Colors', newl2.title)
2434 call assert_equal(['Colors'], newl2.context)
2435 call assert_equal('Line10', newl2.items[0].text)
2436 call g:Xsetlist([], 'f')
Bram Moolenaar2b529bb2016-08-27 13:35:35 +02002437
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002438 " Cannot specify both a non-empty list argument and a dict argument
2439 call assert_fails("call g:Xsetlist([{}], ' ', {})", 'E475:')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002440endfunc
Bram Moolenaard823fa92016-08-12 16:29:27 +02002441
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002442func Test_qf_property()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002443 call Xproperty_tests('c')
2444 call Xproperty_tests('l')
Bram Moolenaaree85df32017-03-19 14:19:50 +01002445endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002446
Bram Moolenaar5b69c222019-01-11 14:50:06 +01002447" Test for setting the current index in the location/quickfix list
2448func Xtest_setqfidx(cchar)
2449 call s:setup_commands(a:cchar)
2450
2451 Xgetexpr "F1:10:1:Line1\nF2:20:2:Line2\nF3:30:3:Line3"
2452 Xgetexpr "F4:10:1:Line1\nF5:20:2:Line2\nF6:30:3:Line3"
2453 Xgetexpr "F7:10:1:Line1\nF8:20:2:Line2\nF9:30:3:Line3"
2454
2455 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 2})
2456 call g:Xsetlist([], 'a', {'nr' : 2, 'idx' : 2})
2457 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 3})
2458 Xolder 2
2459 Xopen
2460 call assert_equal(3, line('.'))
2461 Xnewer
2462 call assert_equal(2, line('.'))
2463 Xnewer
2464 call assert_equal(2, line('.'))
2465 " Update the current index with the quickfix window open
2466 wincmd w
2467 call g:Xsetlist([], 'a', {'nr' : 3, 'idx' : 3})
2468 Xopen
2469 call assert_equal(3, line('.'))
2470 Xclose
2471
2472 " Set the current index to the last entry
2473 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : '$'})
2474 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2475 " A large value should set the index to the last index
2476 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 1})
2477 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 999})
2478 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2479 " Invalid index values
2480 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : -1})
2481 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2482 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 0})
2483 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2484 call g:Xsetlist([], 'a', {'nr' : 1, 'idx' : 'xx'})
2485 call assert_equal(3, g:Xgetlist({'nr' : 1, 'idx' : 0}).idx)
2486 call assert_fails("call g:Xsetlist([], 'a', {'nr':1, 'idx':[]})", 'E745:')
2487
2488 call g:Xsetlist([], 'f')
2489 new | only
2490endfunc
2491
2492func Test_setqfidx()
2493 call Xtest_setqfidx('c')
2494 call Xtest_setqfidx('l')
2495endfunc
2496
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002497" Tests for the QuickFixCmdPre/QuickFixCmdPost autocommands
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002498func QfAutoCmdHandler(loc, cmd)
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002499 call add(g:acmds, a:loc . a:cmd)
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002500endfunc
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002501
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002502func Test_Autocmd()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002503 autocmd QuickFixCmdPre * call QfAutoCmdHandler('pre', expand('<amatch>'))
2504 autocmd QuickFixCmdPost * call QfAutoCmdHandler('post', expand('<amatch>'))
2505
2506 let g:acmds = []
2507 cexpr "F1:10:Line 10"
2508 caddexpr "F1:20:Line 20"
2509 cgetexpr "F1:30:Line 30"
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002510 cexpr ""
2511 caddexpr ""
2512 cgetexpr ""
2513 silent! cexpr non_existing_func()
2514 silent! caddexpr non_existing_func()
2515 silent! cgetexpr non_existing_func()
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002516 let l = ['precexpr',
2517 \ 'postcexpr',
2518 \ 'precaddexpr',
2519 \ 'postcaddexpr',
2520 \ 'precgetexpr',
2521 \ 'postcgetexpr',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002522 \ 'precexpr',
2523 \ 'postcexpr',
2524 \ 'precaddexpr',
2525 \ 'postcaddexpr',
2526 \ 'precgetexpr',
2527 \ 'postcgetexpr',
2528 \ 'precexpr',
2529 \ 'precaddexpr',
2530 \ 'precgetexpr']
2531 call assert_equal(l, g:acmds)
2532
2533 let g:acmds = []
2534 enew! | call append(0, "F2:10:Line 10")
2535 cbuffer!
2536 enew! | call append(0, "F2:20:Line 20")
2537 cgetbuffer
2538 enew! | call append(0, "F2:30:Line 30")
2539 caddbuffer
2540 new
2541 let bnum = bufnr('%')
2542 bunload
2543 exe 'silent! cbuffer! ' . bnum
2544 exe 'silent! cgetbuffer ' . bnum
2545 exe 'silent! caddbuffer ' . bnum
2546 enew!
2547 let l = ['precbuffer',
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002548 \ 'postcbuffer',
2549 \ 'precgetbuffer',
2550 \ 'postcgetbuffer',
2551 \ 'precaddbuffer',
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002552 \ 'postcaddbuffer',
2553 \ 'precbuffer',
2554 \ 'precgetbuffer',
2555 \ 'precaddbuffer']
Bram Moolenaar04c4ce62016-09-01 15:45:58 +02002556 call assert_equal(l, g:acmds)
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002557
2558 call writefile(['Xtest:1:Line1'], 'Xtest')
2559 call writefile([], 'Xempty')
2560 let g:acmds = []
2561 cfile Xtest
2562 caddfile Xtest
2563 cgetfile Xtest
2564 cfile Xempty
2565 caddfile Xempty
2566 cgetfile Xempty
2567 silent! cfile do_not_exist
2568 silent! caddfile do_not_exist
2569 silent! cgetfile do_not_exist
2570 let l = ['precfile',
2571 \ 'postcfile',
2572 \ 'precaddfile',
2573 \ 'postcaddfile',
2574 \ 'precgetfile',
2575 \ 'postcgetfile',
2576 \ 'precfile',
2577 \ 'postcfile',
2578 \ 'precaddfile',
2579 \ 'postcaddfile',
2580 \ 'precgetfile',
2581 \ 'postcgetfile',
2582 \ 'precfile',
2583 \ 'postcfile',
2584 \ 'precaddfile',
2585 \ 'postcaddfile',
2586 \ 'precgetfile',
2587 \ 'postcgetfile']
2588 call assert_equal(l, g:acmds)
2589
2590 let g:acmds = []
2591 helpgrep quickfix
2592 silent! helpgrep non_existing_help_topic
2593 vimgrep test Xtest
2594 vimgrepadd test Xtest
2595 silent! vimgrep non_existing_test Xtest
2596 silent! vimgrepadd non_existing_test Xtest
2597 set makeprg=
2598 silent! make
2599 set makeprg&
2600 let l = ['prehelpgrep',
2601 \ 'posthelpgrep',
2602 \ 'prehelpgrep',
2603 \ 'posthelpgrep',
2604 \ 'previmgrep',
2605 \ 'postvimgrep',
2606 \ 'previmgrepadd',
2607 \ 'postvimgrepadd',
2608 \ 'previmgrep',
2609 \ 'postvimgrep',
2610 \ 'previmgrepadd',
2611 \ 'postvimgrepadd',
2612 \ 'premake',
2613 \ 'postmake']
2614 call assert_equal(l, g:acmds)
2615
2616 if has('unix')
2617 " Run this test only on Unix-like systems. The grepprg may not be set on
2618 " non-Unix systems.
2619 " The following lines are used for the grep test. Don't remove.
2620 " Grep_Autocmd_Text: Match 1
2621 " GrepAdd_Autocmd_Text: Match 2
2622 let g:acmds = []
2623 silent grep Grep_Autocmd_Text test_quickfix.vim
2624 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2625 silent grep abc123def Xtest
2626 silent grepadd abc123def Xtest
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002627 set grepprg=internal
2628 silent grep Grep_Autocmd_Text test_quickfix.vim
2629 silent grepadd GrepAdd_Autocmd_Text test_quickfix.vim
2630 silent lgrep Grep_Autocmd_Text test_quickfix.vim
2631 silent lgrepadd GrepAdd_Autocmd_Text test_quickfix.vim
2632 set grepprg&vim
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002633 let l = ['pregrep',
2634 \ 'postgrep',
2635 \ 'pregrepadd',
2636 \ 'postgrepadd',
2637 \ 'pregrep',
2638 \ 'postgrep',
2639 \ 'pregrepadd',
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002640 \ 'postgrepadd',
2641 \ 'pregrep',
2642 \ 'postgrep',
2643 \ 'pregrepadd',
2644 \ 'postgrepadd',
2645 \ 'prelgrep',
2646 \ 'postlgrep',
2647 \ 'prelgrepadd',
2648 \ 'postlgrepadd']
Bram Moolenaar1ed22762017-11-28 18:03:44 +01002649 call assert_equal(l, g:acmds)
2650 endif
2651
2652 call delete('Xtest')
2653 call delete('Xempty')
Bram Moolenaarb254af32017-12-18 19:48:58 +01002654 au! QuickFixCmdPre
2655 au! QuickFixCmdPost
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002656endfunc
Bram Moolenaar21662be2016-11-06 14:46:44 +01002657
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002658func Test_Autocmd_Exception()
Bram Moolenaar21662be2016-11-06 14:46:44 +01002659 set efm=%m
2660 lgetexpr '?'
2661
2662 try
2663 call DoesNotExit()
2664 catch
2665 lgetexpr '1'
2666 finally
2667 lgetexpr '1'
2668 endtry
2669
2670 call assert_equal('1', getloclist(0)[0].text)
2671
2672 set efm&vim
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002673endfunc
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002674
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002675func Test_caddbuffer_wrong()
2676 " This used to cause a memory access in freed memory.
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002677 let save_efm = &efm
2678 set efm=%EEEE%m,%WWWW,%+CCCC%>%#,%GGGG%.#
2679 cgetexpr ['WWWW', 'EEEE', 'CCCC']
2680 let &efm = save_efm
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002681 caddbuffer
Bram Moolenaar63bed3d2016-11-12 15:36:54 +01002682 bwipe!
2683endfunc
Bram Moolenaar2b946c92016-11-12 18:14:44 +01002684
2685func Test_caddexpr_wrong()
2686 " This used to cause a memory access in freed memory.
2687 cbuffer
2688 cbuffer
2689 copen
2690 let save_efm = &efm
2691 set efm=%
2692 call assert_fails('caddexpr ""', 'E376:')
2693 let &efm = save_efm
2694endfunc
Bram Moolenaar7618e002016-11-13 15:09:26 +01002695
2696func Test_dirstack_cleanup()
2697 " This used to cause a memory access in freed memory.
2698 let save_efm = &efm
2699 lexpr '0'
2700 lopen
2701 fun X(c)
2702 let save_efm=&efm
2703 set efm=%D%f
2704 if a:c == 'c'
2705 caddexpr '::'
2706 else
2707 laddexpr ':0:0'
2708 endif
2709 let &efm=save_efm
2710 endfun
2711 call X('c')
2712 call X('l')
2713 call setqflist([], 'r')
2714 caddbuffer
2715 let &efm = save_efm
2716endfunc
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002717
2718" Tests for jumping to entries from the location list window and quickfix
2719" window
2720func Test_cwindow_jump()
2721 set efm=%f%%%l%%%m
2722 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2723 lopen | only
2724 lfirst
2725 call assert_true(winnr('$') == 2)
2726 call assert_true(winnr() == 1)
2727 " Location list for the new window should be set
2728 call assert_true(getloclist(0)[2].text == 'Line 30')
2729
2730 " Open a scratch buffer
2731 " Open a new window and create a location list
2732 " Open the location list window and close the other window
2733 " Jump to an entry.
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01002734 " Should create a new window and jump to the entry. The scratch buffer
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002735 " should not be used.
2736 enew | only
2737 set buftype=nofile
2738 below new
2739 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2740 lopen
2741 2wincmd c
2742 lnext
2743 call assert_true(winnr('$') == 3)
2744 call assert_true(winnr() == 2)
2745
2746 " Open two windows with two different location lists
2747 " Open the location list window and close the previous window
2748 " Jump to an entry in the location list window
2749 " Should open the file in the first window and not set the location list.
2750 enew | only
2751 lgetexpr ["F1%5%Line 5"]
2752 below new
2753 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2754 lopen
2755 2wincmd c
2756 lnext
2757 call assert_true(winnr() == 1)
2758 call assert_true(getloclist(0)[0].text == 'Line 5')
2759
2760 enew | only
2761 cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2762 copen
2763 cnext
2764 call assert_true(winnr('$') == 2)
2765 call assert_true(winnr() == 1)
2766
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002767 " open the quickfix buffer in two windows and jump to an entry. Should open
2768 " the file in the first quickfix window.
2769 enew | only
2770 copen
2771 let bnum = bufnr('')
2772 exe 'sbuffer ' . bnum
2773 wincmd b
2774 cfirst
2775 call assert_equal(2, winnr())
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002776 call assert_equal('F1', @%)
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002777 enew | only
2778 exe 'sb' bnum
2779 exe 'botright sb' bnum
2780 wincmd t
2781 clast
2782 call assert_equal(2, winnr())
2783 call assert_equal('quickfix', getwinvar(1, '&buftype'))
2784 call assert_equal('quickfix', getwinvar(3, '&buftype'))
2785
Bram Moolenaar4b96df52020-01-26 22:00:26 +01002786 " Jumping to a file from the location list window should find a usable
Bram Moolenaar15a7bdc2019-11-29 22:06:47 +01002787 " window by wrapping around the window list.
2788 enew | only
2789 call setloclist(0, [], 'f')
2790 new | new
2791 lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
2792 lopen
2793 1close
2794 call assert_equal(0, getloclist(3, {'id' : 0}).id)
2795 lnext
2796 call assert_equal(3, winnr())
2797 call assert_equal(getloclist(1, {'id' : 0}).id, getloclist(3, {'id' : 0}).id)
2798
Bram Moolenaar391b1dd2017-03-04 13:47:11 +01002799 enew | only
2800 set efm&vim
2801endfunc
Bram Moolenaaree85df32017-03-19 14:19:50 +01002802
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002803func Test_cwindow_highlight()
2804 CheckScreendump
2805
2806 let lines =<< trim END
Bram Moolenaare00fdf32019-09-15 19:09:42 +02002807 call setline(1, ['some', 'text', 'with', 'matches'])
2808 write XCwindow
2809 vimgrep e XCwindow
2810 redraw
2811 cwindow 4
2812 END
2813 call writefile(lines, 'XtestCwindow')
2814 let buf = RunVimInTerminal('-S XtestCwindow', #{rows: 12})
2815 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_1', {})
2816
2817 call term_sendkeys(buf, ":cnext\<CR>")
2818 call VerifyScreenDump(buf, 'Test_quickfix_cwindow_2', {})
2819
2820 " clean up
2821 call StopVimInTerminal(buf)
2822 call delete('XtestCwindow')
2823 call delete('XCwindow')
2824endfunc
2825
Bram Moolenaaree85df32017-03-19 14:19:50 +01002826func XvimgrepTests(cchar)
2827 call s:setup_commands(a:cchar)
2828
2829 call writefile(['Editor:VIM vim',
2830 \ 'Editor:Emacs EmAcS',
2831 \ 'Editor:Notepad NOTEPAD'], 'Xtestfile1')
2832 call writefile(['Linux', 'MacOS', 'MS-Windows'], 'Xtestfile2')
2833
2834 " Error cases
2835 call assert_fails('Xvimgrep /abc *', 'E682:')
2836
2837 let @/=''
2838 call assert_fails('Xvimgrep // *', 'E35:')
2839
2840 call assert_fails('Xvimgrep abc', 'E683:')
2841 call assert_fails('Xvimgrep a1b2c3 Xtestfile1', 'E480:')
2842 call assert_fails('Xvimgrep pat Xa1b2c3', 'E480:')
2843
2844 Xexpr ""
2845 Xvimgrepadd Notepad Xtestfile1
2846 Xvimgrepadd MacOS Xtestfile2
2847 let l = g:Xgetlist()
2848 call assert_equal(2, len(l))
2849 call assert_equal('Editor:Notepad NOTEPAD', l[0].text)
2850
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01002851 10Xvimgrep #\cvim#g Xtestfile?
Bram Moolenaaree85df32017-03-19 14:19:50 +01002852 let l = g:Xgetlist()
2853 call assert_equal(2, len(l))
2854 call assert_equal(8, l[0].col)
2855 call assert_equal(12, l[1].col)
2856
2857 1Xvimgrep ?Editor? Xtestfile*
2858 let l = g:Xgetlist()
2859 call assert_equal(1, len(l))
2860 call assert_equal('Editor:VIM vim', l[0].text)
2861
2862 edit +3 Xtestfile2
2863 Xvimgrep +\cemacs+j Xtestfile1
2864 let l = g:Xgetlist()
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02002865 call assert_equal('Xtestfile2', @%)
Bram Moolenaaree85df32017-03-19 14:19:50 +01002866 call assert_equal('Editor:Emacs EmAcS', l[0].text)
2867
Bram Moolenaar2225ebb2018-04-24 15:48:11 +02002868 " Test for unloading a buffer after vimgrep searched the buffer
2869 %bwipe
2870 Xvimgrep /Editor/j Xtestfile*
2871 call assert_equal(0, getbufinfo('Xtestfile1')[0].loaded)
2872 call assert_equal([], getbufinfo('Xtestfile2'))
2873
Bram Moolenaaree85df32017-03-19 14:19:50 +01002874 call delete('Xtestfile1')
2875 call delete('Xtestfile2')
2876endfunc
2877
2878" Tests for the :vimgrep command
2879func Test_vimgrep()
2880 call XvimgrepTests('c')
2881 call XvimgrepTests('l')
2882endfunc
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002883
Bram Moolenaarf8c6a172021-01-30 18:09:06 +01002884func Test_vimgrep_wildcards_expanded_once()
2885 new X[id-01] file.txt
2886 call setline(1, 'some text to search for')
2887 vimgrep text %
2888 bwipe!
2889endfunc
2890
Bram Moolenaar1c299432018-10-28 14:36:09 +01002891" Test for incsearch highlighting of the :vimgrep pattern
2892" This test used to cause "E315: ml_get: invalid lnum" errors.
2893func Test_vimgrep_incsearch()
2894 enew
2895 set incsearch
2896 call test_override("char_avail", 1)
2897
2898 call feedkeys(":2vimgrep assert test_quickfix.vim test_cdo.vim\<CR>", "ntx")
2899 let l = getqflist()
2900 call assert_equal(2, len(l))
2901
2902 call test_override("ALL", 0)
2903 set noincsearch
2904endfunc
2905
Bram Moolenaar9f6277b2020-02-11 22:04:02 +01002906" Test vimgrep with the last search pattern not set
2907func Test_vimgrep_with_no_last_search_pat()
2908 let lines =<< trim [SCRIPT]
2909 call assert_fails('vimgrep // *', 'E35:')
2910 call writefile(v:errors, 'Xresult')
2911 qall!
2912 [SCRIPT]
2913 call writefile(lines, 'Xscript')
2914 if RunVim([], [], '--clean -S Xscript')
2915 call assert_equal([], readfile('Xresult'))
2916 endif
2917 call delete('Xscript')
2918 call delete('Xresult')
2919endfunc
2920
Bram Moolenaar997cd1a2020-08-31 22:16:08 +02002921" Test vimgrep without swap file
2922func Test_vimgrep_without_swap_file()
2923 let lines =<< trim [SCRIPT]
2924 vimgrep grep test_c*
2925 call writefile(['done'], 'Xresult')
2926 qall!
2927 [SCRIPT]
2928 call writefile(lines, 'Xscript')
2929 if RunVim([], [], '--clean -n -S Xscript Xscript')
2930 call assert_equal(['done'], readfile('Xresult'))
2931 endif
2932 call delete('Xscript')
2933 call delete('Xresult')
2934endfunc
2935
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002936func Test_vimgrep_existing_swapfile()
2937 call writefile(['match apple with apple'], 'Xapple')
2938 call writefile(['swapfile'], '.Xapple.swp')
2939 let g:foundSwap = 0
2940 let g:ignoreSwapExists = 1
2941 augroup grep
2942 au SwapExists * let foundSwap = 1 | let v:swapchoice = 'e'
2943 augroup END
2944 vimgrep apple Xapple
2945 call assert_equal(1, g:foundSwap)
2946 call assert_match('.Xapple.swo', swapname(''))
2947
2948 call delete('Xapple')
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02002949 call delete('.Xapple.swp')
Bram Moolenaar8ce4b7e2020-08-07 18:12:18 +02002950 augroup grep
2951 au! SwapExists
2952 augroup END
2953 unlet g:ignoreSwapExists
2954endfunc
2955
Bram Moolenaar69f40be2017-04-02 15:15:49 +02002956func XfreeTests(cchar)
2957 call s:setup_commands(a:cchar)
2958
2959 enew | only
2960
2961 " Deleting the quickfix stack should work even When the current list is
2962 " somewhere in the middle of the stack
2963 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2964 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2965 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2966 Xolder
2967 call g:Xsetlist([], 'f')
2968 call assert_equal(0, len(g:Xgetlist()))
2969
2970 " After deleting the stack, adding a new list should create a stack with a
2971 " single list.
2972 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2973 call assert_equal(1, g:Xgetlist({'all':1}).nr)
2974
2975 " Deleting the stack from a quickfix window should update/clear the
2976 " quickfix/location list window.
2977 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2978 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2979 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2980 Xolder
2981 Xwindow
2982 call g:Xsetlist([], 'f')
2983 call assert_equal(2, winnr('$'))
2984 call assert_equal(1, line('$'))
2985 Xclose
2986
2987 " Deleting the stack from a non-quickfix window should update/clear the
2988 " quickfix/location list window.
2989 Xexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
2990 Xexpr ['Xfile2:20:20:Line 20', 'Xfile2:25:25:Line 25']
2991 Xexpr ['Xfile3:30:30:Line 30', 'Xfile3:35:35:Line 35']
2992 Xolder
2993 Xwindow
2994 wincmd p
2995 call g:Xsetlist([], 'f')
2996 call assert_equal(0, len(g:Xgetlist()))
2997 wincmd p
2998 call assert_equal(2, winnr('$'))
2999 call assert_equal(1, line('$'))
3000
3001 " After deleting the location list stack, if the location list window is
3002 " opened, then a new location list should be created. So opening the
3003 " location list window again should not create a new window.
3004 if a:cchar == 'l'
3005 lexpr ['Xfile1:10:10:Line 10', 'Xfile1:15:15:Line 15']
3006 wincmd p
3007 lopen
3008 call assert_equal(2, winnr('$'))
3009 endif
3010 Xclose
3011endfunc
3012
Bram Moolenaar74240d32017-12-10 15:26:15 +01003013" Tests for the quickfix free functionality
Bram Moolenaar69f40be2017-04-02 15:15:49 +02003014func Test_qf_free()
3015 call XfreeTests('c')
3016 call XfreeTests('l')
3017endfunc
Bram Moolenaar6e62da32017-05-28 08:16:25 +02003018
3019" Test for buffer overflow when parsing lines and adding new entries to
3020" the quickfix list.
3021func Test_bufoverflow()
3022 set efm=%f:%l:%m
3023 cgetexpr ['File1:100:' . repeat('x', 1025)]
3024
3025 set efm=%+GCompiler:\ %.%#,%f:%l:%m
3026 cgetexpr ['Compiler: ' . repeat('a', 1015), 'File1:10:Hello World']
3027
3028 set efm=%DEntering\ directory\ %f,%f:%l:%m
3029 cgetexpr ['Entering directory ' . repeat('a', 1006),
3030 \ 'File1:10:Hello World']
3031 set efm&vim
3032endfunc
3033
Bram Moolenaar875feea2017-06-11 16:07:51 +02003034" Tests for getting the quickfix stack size
3035func XsizeTests(cchar)
3036 call s:setup_commands(a:cchar)
3037
3038 call g:Xsetlist([], 'f')
3039 call assert_equal(0, g:Xgetlist({'nr':'$'}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003040 call assert_equal('', g:Xgetlist({'nr':'$', 'all':1}).title)
3041 call assert_equal(0, g:Xgetlist({'nr':0}).nr)
Bram Moolenaar875feea2017-06-11 16:07:51 +02003042
3043 Xexpr "File1:10:Line1"
3044 Xexpr "File2:20:Line2"
3045 Xexpr "File3:30:Line3"
3046 Xolder | Xolder
3047 call assert_equal(3, g:Xgetlist({'nr':'$'}).nr)
3048 call g:Xsetlist([], 'f')
3049
3050 Xexpr "File1:10:Line1"
3051 Xexpr "File2:20:Line2"
3052 Xexpr "File3:30:Line3"
3053 Xolder | Xolder
3054 call g:Xsetlist([], 'a', {'nr':'$', 'title':'Compiler'})
3055 call assert_equal('Compiler', g:Xgetlist({'nr':3, 'all':1}).title)
3056endfunc
3057
3058func Test_Qf_Size()
3059 call XsizeTests('c')
3060 call XsizeTests('l')
3061endfunc
Bram Moolenaar18141832017-06-25 21:17:25 +02003062
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003063func Test_cclose_from_copen()
3064 augroup QF_Test
3065 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003066 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003067 augroup END
3068 copen
3069 augroup QF_Test
3070 au!
3071 augroup END
3072 augroup! QF_Test
3073endfunc
3074
Bram Moolenaar18141832017-06-25 21:17:25 +02003075func Test_cclose_in_autocmd()
3076 " Problem is only triggered if "starting" is zero, so that the OptionsSet
3077 " event will be triggered.
3078 call test_override('starting', 1)
3079 augroup QF_Test
3080 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003081 au FileType qf :call assert_fails(':cclose', 'E788:')
Bram Moolenaar18141832017-06-25 21:17:25 +02003082 augroup END
3083 copen
3084 augroup QF_Test
3085 au!
3086 augroup END
3087 augroup! QF_Test
3088 call test_override('starting', 0)
3089endfunc
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003090
Bram Moolenaar379fb762018-08-30 15:58:28 +02003091" Check that ":file" without an argument is possible even when "curbuf_lock"
3092" is set.
3093func Test_file_from_copen()
3094 " Works without argument.
3095 augroup QF_Test
3096 au!
3097 au FileType qf file
3098 augroup END
3099 copen
3100
3101 augroup QF_Test
3102 au!
3103 augroup END
3104 cclose
3105
3106 " Fails with argument.
3107 augroup QF_Test
3108 au!
Bram Moolenaare2e40752020-09-04 21:18:46 +02003109 au FileType qf call assert_fails(':file foo', 'E788:')
Bram Moolenaar379fb762018-08-30 15:58:28 +02003110 augroup END
3111 copen
3112 augroup QF_Test
3113 au!
3114 augroup END
3115 cclose
3116
3117 augroup! QF_Test
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02003118endfunc
Bram Moolenaar379fb762018-08-30 15:58:28 +02003119
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003120func Test_resize_from_copen()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003121 augroup QF_Test
3122 au!
3123 au FileType qf resize 5
3124 augroup END
3125 try
3126 " This should succeed without any exception. No other buffers are
3127 " involved in the autocmd.
3128 copen
3129 finally
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003130 augroup QF_Test
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003131 au!
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003132 augroup END
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003133 augroup! QF_Test
3134 endtry
Bram Moolenaar9c4feff2017-06-28 22:26:54 +02003135endfunc
Bram Moolenaara8788f42017-07-19 17:06:20 +02003136
Bram Moolenaar33aecb12020-11-14 17:25:51 +01003137func Test_vimgrep_with_textlock()
3138 new
3139
3140 " Simple way to execute something with "textwinlock" set.
3141 " Check that vimgrep without jumping can be executed.
3142 au InsertCharPre * vimgrep /RunTheTest/j runtest.vim
3143 normal ax
3144 let qflist = getqflist()
3145 call assert_true(len(qflist) > 0)
3146 call assert_match('RunTheTest', qflist[0].text)
3147 call setqflist([], 'r')
3148 au! InsertCharPre
3149
3150 " Check that vimgrepadd without jumping can be executed.
3151 au InsertCharPre * vimgrepadd /RunTheTest/j runtest.vim
3152 normal ax
3153 let qflist = getqflist()
3154 call assert_true(len(qflist) > 0)
3155 call assert_match('RunTheTest', qflist[0].text)
3156 call setqflist([], 'r')
3157 au! InsertCharPre
3158
3159 " Check that lvimgrep without jumping can be executed.
3160 au InsertCharPre * lvimgrep /RunTheTest/j runtest.vim
3161 normal ax
3162 let qflist = getloclist(0)
3163 call assert_true(len(qflist) > 0)
3164 call assert_match('RunTheTest', qflist[0].text)
3165 call setloclist(0, [], 'r')
3166 au! InsertCharPre
3167
3168 " Check that lvimgrepadd without jumping can be executed.
3169 au InsertCharPre * lvimgrepadd /RunTheTest/j runtest.vim
3170 normal ax
3171 let qflist = getloclist(0)
3172 call assert_true(len(qflist) > 0)
3173 call assert_match('RunTheTest', qflist[0].text)
3174 call setloclist(0, [], 'r')
3175 au! InsertCharPre
3176
3177 " trying to jump will give an error
3178 au InsertCharPre * vimgrep /RunTheTest/ runtest.vim
3179 call assert_fails('normal ax', 'E565:')
3180 au! InsertCharPre
3181
3182 au InsertCharPre * vimgrepadd /RunTheTest/ runtest.vim
3183 call assert_fails('normal ax', 'E565:')
3184 au! InsertCharPre
3185
3186 au InsertCharPre * lvimgrep /RunTheTest/ runtest.vim
3187 call assert_fails('normal ax', 'E565:')
3188 au! InsertCharPre
3189
3190 au InsertCharPre * lvimgrepadd /RunTheTest/ runtest.vim
3191 call assert_fails('normal ax', 'E565:')
3192 au! InsertCharPre
3193
3194 bwipe!
3195endfunc
3196
Bram Moolenaara8788f42017-07-19 17:06:20 +02003197" Tests for the quickfix buffer b:changedtick variable
3198func Xchangedtick_tests(cchar)
3199 call s:setup_commands(a:cchar)
3200
3201 new | only
3202
3203 Xexpr "" | Xexpr "" | Xexpr ""
3204
3205 Xopen
3206 Xolder
3207 Xolder
3208 Xaddexpr "F1:10:Line10"
3209 Xaddexpr "F2:20:Line20"
3210 call g:Xsetlist([{"filename":"F3", "lnum":30, "text":"Line30"}], 'a')
3211 call g:Xsetlist([], 'f')
3212 call assert_equal(8, getbufvar('%', 'changedtick'))
3213 Xclose
3214endfunc
3215
3216func Test_changedtick()
Bram Moolenaarae338332017-08-11 20:25:26 +02003217 call Xchangedtick_tests('c')
3218 call Xchangedtick_tests('l')
3219endfunc
3220
3221" Tests for parsing an expression using setqflist()
3222func Xsetexpr_tests(cchar)
3223 call s:setup_commands(a:cchar)
3224
3225 let t = ["File1:10:Line10", "File1:20:Line20"]
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003226 call g:Xsetlist([], ' ', {'lines' : t})
3227 call g:Xsetlist([], 'a', {'lines' : ["File1:30:Line30"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003228
3229 let l = g:Xgetlist()
3230 call assert_equal(3, len(l))
3231 call assert_equal(20, l[1].lnum)
3232 call assert_equal('Line30', l[2].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003233 call g:Xsetlist([], 'r', {'lines' : ["File2:5:Line5"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003234 let l = g:Xgetlist()
3235 call assert_equal(1, len(l))
3236 call assert_equal('Line5', l[0].text)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003237 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : 10}))
3238 call assert_equal(-1, g:Xsetlist([], 'a', {'lines' : "F1:10:L10"}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003239
3240 call g:Xsetlist([], 'f')
3241 " Add entries to multiple lists
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003242 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:10:Line10"]})
3243 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:20:Line20"]})
3244 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["File1:15:Line15"]})
3245 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["File2:25:Line25"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003246 call assert_equal('Line15', g:Xgetlist({'nr':1, 'items':1}).items[1].text)
3247 call assert_equal('Line25', g:Xgetlist({'nr':2, 'items':1}).items[1].text)
Bram Moolenaar36538222017-09-02 19:51:44 +02003248
3249 " Adding entries using a custom efm
3250 set efm&
3251 call g:Xsetlist([], ' ', {'efm' : '%f#%l#%m',
3252 \ 'lines' : ["F1#10#L10", "F2#20#L20"]})
3253 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3254 call g:Xsetlist([], 'a', {'efm' : '%f#%l#%m', 'lines' : ["F3:30:L30"]})
3255 call assert_equal('F3:30:L30', g:Xgetlist({'items':1}).items[2].text)
3256 call assert_equal(20, g:Xgetlist({'items':1}).items[1].lnum)
3257 call assert_equal(-1, g:Xsetlist([], 'a', {'efm' : [],
3258 \ 'lines' : ['F1:10:L10']}))
Bram Moolenaarae338332017-08-11 20:25:26 +02003259endfunc
3260
3261func Test_setexpr()
3262 call Xsetexpr_tests('c')
3263 call Xsetexpr_tests('l')
3264endfunc
3265
3266" Tests for per quickfix/location list directory stack
3267func Xmultidirstack_tests(cchar)
3268 call s:setup_commands(a:cchar)
3269
3270 call g:Xsetlist([], 'f')
3271 Xexpr "" | Xexpr ""
3272
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003273 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["Entering dir 'Xone/a'"]})
3274 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["Entering dir 'Xtwo/a'"]})
3275 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["one.txt:3:one one one"]})
3276 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["two.txt:5:two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003277
3278 let l1 = g:Xgetlist({'nr':1, 'items':1})
3279 let l2 = g:Xgetlist({'nr':2, 'items':1})
3280 call assert_equal('Xone/a/one.txt', bufname(l1.items[1].bufnr))
3281 call assert_equal(3, l1.items[1].lnum)
3282 call assert_equal('Xtwo/a/two.txt', bufname(l2.items[1].bufnr))
3283 call assert_equal(5, l2.items[1].lnum)
3284endfunc
3285
3286func Test_multidirstack()
3287 call mkdir('Xone/a', 'p')
3288 call mkdir('Xtwo/a', 'p')
3289 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3290 call writefile(lines, 'Xone/a/one.txt')
3291 call writefile(lines, 'Xtwo/a/two.txt')
3292 let save_efm = &efm
3293 set efm=%DEntering\ dir\ '%f',%f:%l:%m,%XLeaving\ dir\ '%f'
3294
3295 call Xmultidirstack_tests('c')
3296 call Xmultidirstack_tests('l')
3297
3298 let &efm = save_efm
3299 call delete('Xone', 'rf')
3300 call delete('Xtwo', 'rf')
3301endfunc
3302
3303" Tests for per quickfix/location list file stack
3304func Xmultifilestack_tests(cchar)
3305 call s:setup_commands(a:cchar)
3306
3307 call g:Xsetlist([], 'f')
3308 Xexpr "" | Xexpr ""
3309
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003310 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["[one.txt]"]})
3311 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["[two.txt]"]})
3312 call g:Xsetlist([], 'a', {'nr' : 1, 'lines' : ["(3,5) one one one"]})
3313 call g:Xsetlist([], 'a', {'nr' : 2, 'lines' : ["(5,9) two two two"]})
Bram Moolenaarae338332017-08-11 20:25:26 +02003314
3315 let l1 = g:Xgetlist({'nr':1, 'items':1})
3316 let l2 = g:Xgetlist({'nr':2, 'items':1})
3317 call assert_equal('one.txt', bufname(l1.items[1].bufnr))
3318 call assert_equal(3, l1.items[1].lnum)
3319 call assert_equal('two.txt', bufname(l2.items[1].bufnr))
3320 call assert_equal(5, l2.items[1].lnum)
Bram Moolenaare333e792018-04-08 13:27:39 +02003321
3322 " Test for start of a new error line in the same line where a previous
3323 " error line ends with a file stack.
3324 let efm_val = 'Error\ l%l\ in\ %f,'
3325 let efm_val .= '%-P%>(%f%r,Error\ l%l\ in\ %m,%-Q)%r'
3326 let l = g:Xgetlist({'lines' : [
3327 \ '(one.txt',
3328 \ 'Error l4 in one.txt',
3329 \ ') (two.txt',
3330 \ 'Error l6 in two.txt',
3331 \ ')',
3332 \ 'Error l8 in one.txt'
3333 \ ], 'efm' : efm_val})
3334 call assert_equal(3, len(l.items))
3335 call assert_equal('one.txt', bufname(l.items[0].bufnr))
3336 call assert_equal(4, l.items[0].lnum)
3337 call assert_equal('one.txt', l.items[0].text)
3338 call assert_equal('two.txt', bufname(l.items[1].bufnr))
3339 call assert_equal(6, l.items[1].lnum)
3340 call assert_equal('two.txt', l.items[1].text)
3341 call assert_equal('one.txt', bufname(l.items[2].bufnr))
3342 call assert_equal(8, l.items[2].lnum)
3343 call assert_equal('', l.items[2].text)
Bram Moolenaarae338332017-08-11 20:25:26 +02003344endfunc
3345
3346func Test_multifilestack()
3347 let lines = ['1', '2', 'one one one', '4', 'two two two', '6', '7']
3348 call writefile(lines, 'one.txt')
3349 call writefile(lines, 'two.txt')
3350 let save_efm = &efm
3351 set efm=%+P[%f],(%l\\,%c)\ %m,%-Q
3352
3353 call Xmultifilestack_tests('c')
3354 call Xmultifilestack_tests('l')
3355
3356 let &efm = save_efm
3357 call delete('one.txt')
3358 call delete('two.txt')
3359endfunc
3360
3361" Tests for per buffer 'efm' setting
3362func Test_perbuf_efm()
3363 call writefile(["File1-10-Line10"], 'one.txt')
3364 call writefile(["File2#20#Line20"], 'two.txt')
3365 set efm=%f#%l#%m
3366 new | only
3367 new
3368 setlocal efm=%f-%l-%m
3369 cfile one.txt
3370 wincmd w
3371 caddfile two.txt
3372
3373 let l = getqflist()
3374 call assert_equal(10, l[0].lnum)
3375 call assert_equal('Line20', l[1].text)
3376
3377 set efm&
3378 new | only
3379 call delete('one.txt')
3380 call delete('two.txt')
Bram Moolenaara8788f42017-07-19 17:06:20 +02003381endfunc
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003382
3383" Open multiple help windows using ":lhelpgrep
3384" This test used to crash Vim
3385func Test_Multi_LL_Help()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02003386 new | only
3387 lhelpgrep window
3388 lopen
3389 e#
3390 lhelpgrep buffer
3391 call assert_equal(3, winnr('$'))
3392 call assert_true(len(getloclist(1)) != 0)
3393 call assert_true(len(getloclist(2)) != 0)
3394 new | only
Bram Moolenaard28cc3f2017-07-27 22:03:50 +02003395endfunc
Bram Moolenaar55b69262017-08-13 13:42:01 +02003396
3397" Tests for adding new quickfix lists using setqflist()
3398func XaddQf_tests(cchar)
3399 call s:setup_commands(a:cchar)
3400
3401 " Create a new list using ' ' for action
3402 call g:Xsetlist([], 'f')
3403 call g:Xsetlist([], ' ', {'title' : 'Test1'})
3404 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3405 call assert_equal(1, l.nr)
3406 call assert_equal('Test1', l.title)
3407
3408 " Create a new list using ' ' for action and '$' for 'nr'
3409 call g:Xsetlist([], 'f')
3410 call g:Xsetlist([], ' ', {'title' : 'Test2', 'nr' : '$'})
3411 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3412 call assert_equal(1, l.nr)
3413 call assert_equal('Test2', l.title)
3414
3415 " Create a new list using 'a' for action
3416 call g:Xsetlist([], 'f')
3417 call g:Xsetlist([], 'a', {'title' : 'Test3'})
3418 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3419 call assert_equal(1, l.nr)
3420 call assert_equal('Test3', l.title)
3421
3422 " Create a new list using 'a' for action and '$' for 'nr'
3423 call g:Xsetlist([], 'f')
3424 call g:Xsetlist([], 'a', {'title' : 'Test3', 'nr' : '$'})
3425 call g:Xsetlist([], 'a', {'title' : 'Test4'})
3426 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3427 call assert_equal(1, l.nr)
3428 call assert_equal('Test4', l.title)
3429
3430 " Adding a quickfix list should remove all the lists following the current
3431 " list.
3432 Xexpr "" | Xexpr "" | Xexpr ""
3433 silent! 10Xolder
3434 call g:Xsetlist([], ' ', {'title' : 'Test5'})
3435 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3436 call assert_equal(2, l.nr)
3437 call assert_equal('Test5', l.title)
3438
3439 " Add a quickfix list using '$' as the list number.
3440 let lastqf = g:Xgetlist({'nr':'$'}).nr
3441 silent! 99Xolder
3442 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test6'})
3443 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3444 call assert_equal(lastqf + 1, l.nr)
3445 call assert_equal('Test6', l.title)
3446
3447 " Add a quickfix list using 'nr' set to one more than the quickfix
3448 " list size.
3449 let lastqf = g:Xgetlist({'nr':'$'}).nr
3450 silent! 99Xolder
3451 call g:Xsetlist([], ' ', {'nr' : lastqf + 1, 'title' : 'Test7'})
3452 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3453 call assert_equal(lastqf + 1, l.nr)
3454 call assert_equal('Test7', l.title)
3455
3456 " Add a quickfix list to a stack with 10 lists using 'nr' set to '$'
3457 exe repeat('Xexpr "" |', 9) . 'Xexpr ""'
3458 silent! 99Xolder
3459 call g:Xsetlist([], ' ', {'nr' : '$', 'title' : 'Test8'})
3460 let l = g:Xgetlist({'nr' : '$', 'all' : 1})
3461 call assert_equal(10, l.nr)
3462 call assert_equal('Test8', l.title)
3463
3464 " Add a quickfix list using 'nr' set to a value greater than 10
3465 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 12, 'title' : 'Test9'}))
3466
3467 " Try adding a quickfix list with 'nr' set to a value greater than the
3468 " quickfix list size but less than 10.
3469 call g:Xsetlist([], 'f')
3470 Xexpr "" | Xexpr "" | Xexpr ""
3471 silent! 99Xolder
3472 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : 8, 'title' : 'Test10'}))
3473
3474 " Add a quickfix list using 'nr' set to a some string or list
3475 call assert_equal(-1, g:Xsetlist([], ' ', {'nr' : [1,2], 'title' : 'Test11'}))
3476endfunc
3477
3478func Test_add_qf()
3479 call XaddQf_tests('c')
3480 call XaddQf_tests('l')
3481endfunc
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003482
3483" Test for getting the quickfix list items from some text without modifying
3484" the quickfix stack
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003485func XgetListFromLines(cchar)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003486 call s:setup_commands(a:cchar)
3487 call g:Xsetlist([], 'f')
3488
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003489 let l = g:Xgetlist({'lines' : ["File2:20:Line20", "File2:30:Line30"]}).items
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003490 call assert_equal(2, len(l))
3491 call assert_equal(30, l[1].lnum)
3492
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003493 call assert_equal({}, g:Xgetlist({'lines' : 10}))
3494 call assert_equal({}, g:Xgetlist({'lines' : 'File1:10:Line10'}))
3495 call assert_equal([], g:Xgetlist({'lines' : []}).items)
3496 call assert_equal([], g:Xgetlist({'lines' : [10, 20]}).items)
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003497
Bram Moolenaar36538222017-09-02 19:51:44 +02003498 " Parse text using a custom efm
3499 set efm&
3500 let l = g:Xgetlist({'lines':['File3#30#Line30'], 'efm' : '%f#%l#%m'}).items
3501 call assert_equal('Line30', l[0].text)
3502 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : '%f-%l-%m'}).items
3503 call assert_equal('File3:30:Line30', l[0].text)
3504 let l = g:Xgetlist({'lines':['File3:30:Line30'], 'efm' : [1,2]})
3505 call assert_equal({}, l)
3506 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':'%2'})", 'E376:')
3507 call assert_fails("call g:Xgetlist({'lines':['abc'], 'efm':''})", 'E378:')
3508
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003509 " Make sure that the quickfix stack is not modified
3510 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
3511endfunc
3512
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003513func Test_get_list_from_lines()
3514 call XgetListFromLines('c')
3515 call XgetListFromLines('l')
Bram Moolenaar7adf06f2017-08-27 15:23:41 +02003516endfunc
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003517
3518" Tests for the quickfix list id
3519func Xqfid_tests(cchar)
3520 call s:setup_commands(a:cchar)
3521
3522 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003523 call assert_equal(0, g:Xgetlist({'id':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003524 Xexpr ''
3525 let start_id = g:Xgetlist({'id' : 0}).id
3526 Xexpr '' | Xexpr ''
3527 Xolder
3528 call assert_equal(start_id, g:Xgetlist({'id':0, 'nr':1}).id)
3529 call assert_equal(start_id + 1, g:Xgetlist({'id':0, 'nr':0}).id)
3530 call assert_equal(start_id + 2, g:Xgetlist({'id':0, 'nr':'$'}).id)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003531 call assert_equal(0, g:Xgetlist({'id':0, 'nr':99}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003532 call assert_equal(2, g:Xgetlist({'id':start_id + 1, 'nr':0}).nr)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003533 call assert_equal(0, g:Xgetlist({'id':99, 'nr':0}).id)
3534 call assert_equal(0, g:Xgetlist({'id':"abc", 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003535
3536 call g:Xsetlist([], 'a', {'id':start_id, 'context':[1,2]})
3537 call assert_equal([1,2], g:Xgetlist({'nr':1, 'context':1}).context)
Bram Moolenaar2c809b72017-09-01 18:34:02 +02003538 call g:Xsetlist([], 'a', {'id':start_id+1, 'lines':['F1:10:L10']})
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003539 call assert_equal('L10', g:Xgetlist({'nr':2, 'items':1}).items[0].text)
3540 call assert_equal(-1, g:Xsetlist([], 'a', {'id':999, 'title':'Vim'}))
3541 call assert_equal(-1, g:Xsetlist([], 'a', {'id':'abc', 'title':'Vim'}))
3542
3543 let qfid = g:Xgetlist({'id':0, 'nr':0})
3544 call g:Xsetlist([], 'f')
Bram Moolenaara6d48492017-12-12 22:45:31 +01003545 call assert_equal(0, g:Xgetlist({'id':qfid, 'nr':0}).id)
Bram Moolenaara539f4f2017-08-30 20:33:55 +02003546endfunc
3547
3548func Test_qf_id()
3549 call Xqfid_tests('c')
3550 call Xqfid_tests('l')
3551endfunc
Bram Moolenaar74240d32017-12-10 15:26:15 +01003552
3553func Xqfjump_tests(cchar)
3554 call s:setup_commands(a:cchar)
3555
3556 call writefile(["Line1\tFoo", "Line2"], 'F1')
3557 call writefile(["Line1\tBar", "Line2"], 'F2')
3558 call writefile(["Line1\tBaz", "Line2"], 'F3')
3559
3560 call g:Xsetlist([], 'f')
3561
3562 " Tests for
3563 " Jumping to a line using a pattern
3564 " Jumping to a column greater than the last column in a line
3565 " Jumping to a line greater than the last line in the file
3566 let l = []
3567 for i in range(1, 7)
3568 call add(l, {})
3569 endfor
3570 let l[0].filename='F1'
3571 let l[0].pattern='Line1'
3572 let l[1].filename='F2'
3573 let l[1].pattern='Line1'
3574 let l[2].filename='F3'
3575 let l[2].pattern='Line1'
3576 let l[3].filename='F3'
3577 let l[3].lnum=1
3578 let l[3].col=9
3579 let l[3].vcol=1
3580 let l[4].filename='F3'
3581 let l[4].lnum=99
3582 let l[5].filename='F3'
3583 let l[5].lnum=1
3584 let l[5].col=99
3585 let l[5].vcol=1
3586 let l[6].filename='F3'
3587 let l[6].pattern='abcxyz'
3588
3589 call g:Xsetlist([], ' ', {'items' : l})
3590 Xopen | only
3591 2Xnext
3592 call assert_equal(3, g:Xgetlist({'idx' : 0}).idx)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02003593 call assert_equal('F3', @%)
Bram Moolenaar74240d32017-12-10 15:26:15 +01003594 Xnext
3595 call assert_equal(7, col('.'))
3596 Xnext
3597 call assert_equal(2, line('.'))
3598 Xnext
3599 call assert_equal(9, col('.'))
3600 2
3601 Xnext
3602 call assert_equal(2, line('.'))
3603
3604 if a:cchar == 'l'
3605 " When jumping to a location list entry in the location list window and
3606 " no usable windows are available, then a new window should be opened.
3607 enew! | new | only
3608 call g:Xsetlist([], 'f')
3609 setlocal buftype=nofile
3610 new
3611 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']})
3612 Xopen
3613 let winid = win_getid()
3614 wincmd p
3615 close
3616 call win_gotoid(winid)
3617 Xnext
3618 call assert_equal(3, winnr('$'))
3619 call assert_equal(1, winnr())
3620 call assert_equal(2, line('.'))
3621
3622 " When jumping to an entry in the location list window and the window
3623 " associated with the location list is not present and a window containing
3624 " the file is already present, then that window should be used.
3625 close
3626 belowright new
3627 call g:Xsetlist([], 'f')
3628 edit F3
3629 call win_gotoid(winid)
3630 Xlast
3631 call assert_equal(3, winnr())
3632 call assert_equal(6, g:Xgetlist({'size' : 1}).size)
3633 call assert_equal(winid, g:Xgetlist({'winid' : 1}).winid)
3634 endif
3635
3636 " Cleanup
3637 enew!
3638 new | only
3639
3640 call delete('F1')
3641 call delete('F2')
3642 call delete('F3')
3643endfunc
3644
3645func Test_qfjump()
3646 call Xqfjump_tests('c')
3647 call Xqfjump_tests('l')
3648endfunc
Bram Moolenaara6d48492017-12-12 22:45:31 +01003649
3650" Tests for the getqflist() and getloclist() functions when the list is not
3651" present or is empty
3652func Xgetlist_empty_tests(cchar)
3653 call s:setup_commands(a:cchar)
3654
3655 " Empty quickfix stack
3656 call g:Xsetlist([], 'f')
3657 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3658 call assert_equal(0, g:Xgetlist({'id' : 0}).id)
3659 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3660 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3661 call assert_equal(0, g:Xgetlist({'nr' : 0}).nr)
3662 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3663 call assert_equal('', g:Xgetlist({'title' : 0}).title)
3664 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003665 call assert_equal(0, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003666 if a:cchar == 'c'
3667 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003668 \ 'items' : [], 'nr' : 0, 'size' : 0, 'qfbufnr' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003669 \ 'title' : '', 'winid' : 0, 'changedtick': 0,
3670 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003671 else
3672 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0,
3673 \ 'items' : [], 'nr' : 0, 'size' : 0, 'title' : '',
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003674 \ 'winid' : 0, 'changedtick': 0, 'filewinid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003675 \ 'qfbufnr' : 0, 'quickfixtextfunc' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003676 \ g:Xgetlist({'all' : 0}))
3677 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003678
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003679 " Quickfix window with empty stack
3680 silent! Xopen
3681 let qfwinid = (a:cchar == 'c') ? win_getid() : 0
Bram Moolenaar647e24b2019-03-17 16:39:46 +01003682 let qfbufnr = (a:cchar == 'c') ? bufnr('') : 0
Bram Moolenaar2ec364e2018-01-27 11:52:13 +01003683 call assert_equal(qfwinid, g:Xgetlist({'winid' : 0}).winid)
3684 Xclose
3685
Bram Moolenaara6d48492017-12-12 22:45:31 +01003686 " Empty quickfix list
3687 Xexpr ""
3688 call assert_equal('', g:Xgetlist({'context' : 0}).context)
3689 call assert_notequal(0, g:Xgetlist({'id' : 0}).id)
3690 call assert_equal(0, g:Xgetlist({'idx' : 0}).idx)
3691 call assert_equal([], g:Xgetlist({'items' : 0}).items)
3692 call assert_notequal(0, g:Xgetlist({'nr' : 0}).nr)
3693 call assert_equal(0, g:Xgetlist({'size' : 0}).size)
3694 call assert_notequal('', g:Xgetlist({'title' : 0}).title)
3695 call assert_equal(0, g:Xgetlist({'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003696 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
Bram Moolenaara6d48492017-12-12 22:45:31 +01003697
3698 let qfid = g:Xgetlist({'id' : 0}).id
3699 call g:Xsetlist([], 'f')
3700
3701 " Non-existing quickfix identifier
3702 call assert_equal('', g:Xgetlist({'id' : qfid, 'context' : 0}).context)
3703 call assert_equal(0, g:Xgetlist({'id' : qfid}).id)
3704 call assert_equal(0, g:Xgetlist({'id' : qfid, 'idx' : 0}).idx)
3705 call assert_equal([], g:Xgetlist({'id' : qfid, 'items' : 0}).items)
3706 call assert_equal(0, g:Xgetlist({'id' : qfid, 'nr' : 0}).nr)
3707 call assert_equal(0, g:Xgetlist({'id' : qfid, 'size' : 0}).size)
3708 call assert_equal('', g:Xgetlist({'id' : qfid, 'title' : 0}).title)
3709 call assert_equal(0, g:Xgetlist({'id' : qfid, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003710 call assert_equal(0, g:Xgetlist({'id' : qfid, '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 \ 'qfbufnr' : qfbufnr, 'quickfixtextfunc' : '',
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003715 \ 'changedtick' : 0}, g:Xgetlist({'id' : qfid, 'all' : 0}))
3716 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' : ''},
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003721 \ g:Xgetlist({'id' : qfid, 'all' : 0}))
3722 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003723
3724 " Non-existing quickfix list number
3725 call assert_equal('', g:Xgetlist({'nr' : 5, 'context' : 0}).context)
3726 call assert_equal(0, g:Xgetlist({'nr' : 5}).nr)
3727 call assert_equal(0, g:Xgetlist({'nr' : 5, 'idx' : 0}).idx)
3728 call assert_equal([], g:Xgetlist({'nr' : 5, 'items' : 0}).items)
3729 call assert_equal(0, g:Xgetlist({'nr' : 5, 'id' : 0}).id)
3730 call assert_equal(0, g:Xgetlist({'nr' : 5, 'size' : 0}).size)
3731 call assert_equal('', g:Xgetlist({'nr' : 5, 'title' : 0}).title)
3732 call assert_equal(0, g:Xgetlist({'nr' : 5, 'winid' : 0}).winid)
Bram Moolenaarb254af32017-12-18 19:48:58 +01003733 call assert_equal(0, g:Xgetlist({'nr' : 5, 'changedtick' : 0}).changedtick)
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003734 if a:cchar == 'c'
3735 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3736 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003737 \ 'changedtick' : 0, 'qfbufnr' : qfbufnr,
3738 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003739 else
3740 call assert_equal({'context' : '', 'id' : 0, 'idx' : 0, 'items' : [],
3741 \ 'nr' : 0, 'size' : 0, 'title' : '', 'winid' : 0,
Bram Moolenaard43906d2020-07-20 21:31:32 +02003742 \ 'changedtick' : 0, 'filewinid' : 0, 'qfbufnr' : 0,
3743 \ 'quickfixtextfunc' : ''}, g:Xgetlist({'nr' : 5, 'all' : 0}))
Bram Moolenaarc9cc9c72018-09-02 15:18:42 +02003744 endif
Bram Moolenaara6d48492017-12-12 22:45:31 +01003745endfunc
3746
3747func Test_getqflist()
3748 call Xgetlist_empty_tests('c')
3749 call Xgetlist_empty_tests('l')
3750endfunc
Bram Moolenaarb254af32017-12-18 19:48:58 +01003751
Bram Moolenaara0ca7d02017-12-19 10:22:19 +01003752func Test_getqflist_invalid_nr()
3753 " The following commands used to crash Vim
3754 cexpr ""
3755 call getqflist({'nr' : $XXX_DOES_NOT_EXIST_XXX})
3756
3757 " Cleanup
3758 call setqflist([], 'r')
3759endfunc
3760
Bram Moolenaarb254af32017-12-18 19:48:58 +01003761" Tests for the quickfix/location list changedtick
3762func Xqftick_tests(cchar)
3763 call s:setup_commands(a:cchar)
3764
3765 call g:Xsetlist([], 'f')
3766
3767 Xexpr "F1:10:Line10"
3768 let qfid = g:Xgetlist({'id' : 0}).id
3769 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3770 Xaddexpr "F2:20:Line20\nF2:21:Line21"
3771 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3772 call g:Xsetlist([], 'a', {'lines' : ["F3:30:Line30", "F3:31:Line31"]})
3773 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
3774 call g:Xsetlist([], 'r', {'lines' : ["F4:40:Line40"]})
3775 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
3776 call g:Xsetlist([], 'a', {'title' : 'New Title'})
3777 call assert_equal(5, g:Xgetlist({'changedtick' : 0}).changedtick)
3778
3779 enew!
3780 call append(0, ["F5:50:L50", "F6:60:L60"])
3781 Xaddbuffer
3782 call assert_equal(6, g:Xgetlist({'changedtick' : 0}).changedtick)
3783 enew!
3784
3785 call g:Xsetlist([], 'a', {'context' : {'bus' : 'pci'}})
3786 call assert_equal(7, g:Xgetlist({'changedtick' : 0}).changedtick)
3787 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3788 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'a')
3789 call assert_equal(8, g:Xgetlist({'changedtick' : 0}).changedtick)
3790 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3791 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], ' ')
3792 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3793 call g:Xsetlist([{'filename' : 'F7', 'lnum' : 10, 'text' : 'L7'},
3794 \ {'filename' : 'F7', 'lnum' : 11, 'text' : 'L11'}], 'r')
3795 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3796
3797 call writefile(["F8:80:L80", "F8:81:L81"], "Xone")
3798 Xfile Xone
3799 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3800 Xaddfile Xone
3801 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
3802
3803 " Test case for updating a non-current quickfix list
3804 call g:Xsetlist([], 'f')
3805 Xexpr "F1:1:L1"
3806 Xexpr "F2:2:L2"
3807 call g:Xsetlist([], 'a', {'nr' : 1, "lines" : ["F10:10:L10"]})
3808 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
3809 call assert_equal(2, g:Xgetlist({'nr' : 1, 'changedtick' : 0}).changedtick)
3810
3811 call delete("Xone")
3812endfunc
3813
3814func Test_qf_tick()
3815 call Xqftick_tests('c')
3816 call Xqftick_tests('l')
3817endfunc
Bram Moolenaar12237442017-12-19 12:38:52 +01003818
Bram Moolenaarc631f2d2018-08-21 21:58:13 +02003819" Test helpgrep with lang specifier
3820func Xtest_helpgrep_with_lang_specifier(cchar)
3821 call s:setup_commands(a:cchar)
3822 Xhelpgrep Vim@en
3823 call assert_equal('help', &filetype)
3824 call assert_notequal(0, g:Xgetlist({'nr' : '$'}).nr)
3825 new | only
3826endfunc
3827
3828func Test_helpgrep_with_lang_specifier()
3829 call Xtest_helpgrep_with_lang_specifier('c')
3830 call Xtest_helpgrep_with_lang_specifier('l')
3831endfunc
3832
Bram Moolenaar12237442017-12-19 12:38:52 +01003833" The following test used to crash Vim.
3834" Open the location list window and close the regular window associated with
3835" the location list. When the garbage collection runs now, it incorrectly
3836" marks the location list context as not in use and frees the context.
3837func Test_ll_window_ctx()
3838 call setloclist(0, [], 'f')
3839 call setloclist(0, [], 'a', {'context' : []})
3840 lopen | only
3841 call test_garbagecollect_now()
3842 echo getloclist(0, {'context' : 1}).context
3843 enew | only
3844endfunc
3845
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003846" The following test used to crash vim
3847func Test_lfile_crash()
3848 sp Xtest
3849 au QuickFixCmdPre * bw
Bram Moolenaare2e40752020-09-04 21:18:46 +02003850 call assert_fails('lfile', 'E40:')
Bram Moolenaar14a4deb2017-12-19 16:48:55 +01003851 au! QuickFixCmdPre
3852endfunc
Bram Moolenaar3c097222017-12-21 20:54:49 +01003853
3854" The following test used to crash vim
3855func Test_lbuffer_crash()
3856 sv Xtest
3857 augroup QF_Test
3858 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003859 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bw
Bram Moolenaar3c097222017-12-21 20:54:49 +01003860 augroup END
3861 lbuffer
3862 augroup QF_Test
3863 au!
3864 augroup END
3865endfunc
3866
3867" The following test used to crash vim
3868func Test_lexpr_crash()
3869 augroup QF_Test
3870 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003871 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003872 augroup END
3873 lexpr ""
3874 augroup QF_Test
3875 au!
3876 augroup END
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003877
Bram Moolenaar3c097222017-12-21 20:54:49 +01003878 enew | only
Bram Moolenaar9f84ded2018-10-20 20:54:02 +02003879 augroup QF_Test
3880 au!
3881 au BufNew * call setloclist(0, [], 'f')
3882 augroup END
3883 lexpr 'x:1:x'
3884 augroup QF_Test
3885 au!
3886 augroup END
3887
3888 enew | only
3889 lexpr ''
3890 lopen
3891 augroup QF_Test
3892 au!
3893 au FileType * call setloclist(0, [], 'f')
3894 augroup END
3895 lexpr ''
3896 augroup QF_Test
3897 au!
3898 augroup END
Bram Moolenaar3c097222017-12-21 20:54:49 +01003899endfunc
3900
3901" The following test used to crash Vim
3902func Test_lvimgrep_crash()
3903 sv Xtest
3904 augroup QF_Test
3905 au!
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01003906 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call setloclist(0, [], 'f')
Bram Moolenaar3c097222017-12-21 20:54:49 +01003907 augroup END
3908 lvimgrep quickfix test_quickfix.vim
3909 augroup QF_Test
3910 au!
3911 augroup END
Bram Moolenaarb6f14802018-10-21 18:47:43 +02003912
3913 new | only
3914 augroup QF_Test
3915 au!
3916 au BufEnter * call setloclist(0, [], 'r')
3917 augroup END
3918 call assert_fails('lvimgrep Test_lvimgrep_crash *', 'E926:')
3919 augroup QF_Test
3920 au!
3921 augroup END
3922
Bram Moolenaar3c097222017-12-21 20:54:49 +01003923 enew | only
3924endfunc
Bram Moolenaarde046542017-12-26 13:53:11 +01003925
Bram Moolenaar2573af32020-03-14 17:21:34 +01003926func Test_lvimgrep_crash2()
3927 au BufNewFile x sfind
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +02003928 call assert_fails('lvimgrep x x', 'E471:')
3929 call assert_fails('lvimgrep x x x', 'E471:')
Bram Moolenaar2573af32020-03-14 17:21:34 +01003930
3931 au! BufNewFile
3932endfunc
3933
Bram Moolenaarde046542017-12-26 13:53:11 +01003934" Test for the position of the quickfix and location list window
3935func Test_qfwin_pos()
3936 " Open two windows
3937 new | only
3938 new
3939 cexpr ['F1:10:L10']
3940 copen
3941 " Quickfix window should be the bottom most window
3942 call assert_equal(3, winnr())
3943 close
3944 " Open at the very top
3945 wincmd t
3946 topleft copen
3947 call assert_equal(1, winnr())
3948 close
3949 " open left of the current window
3950 wincmd t
3951 below new
3952 leftabove copen
3953 call assert_equal(2, winnr())
3954 close
3955 " open right of the current window
3956 rightbelow copen
3957 call assert_equal(3, winnr())
3958 close
3959endfunc
Bram Moolenaare1bb8792018-04-06 22:58:23 +02003960
3961" Tests for quickfix/location lists changed by autocommands when
3962" :vimgrep/:lvimgrep commands are running.
3963func Test_vimgrep_autocmd()
3964 call setqflist([], 'f')
3965 call writefile(['stars'], 'Xtest1.txt')
3966 call writefile(['stars'], 'Xtest2.txt')
3967
3968 " Test 1:
3969 " When searching for a pattern using :vimgrep, if the quickfix list is
3970 " changed by an autocmd, the results should be added to the correct quickfix
3971 " list.
3972 autocmd BufRead Xtest2.txt cexpr '' | cexpr ''
3973 silent vimgrep stars Xtest*.txt
3974 call assert_equal(1, getqflist({'nr' : 0}).nr)
3975 call assert_equal(3, getqflist({'nr' : '$'}).nr)
3976 call assert_equal('Xtest2.txt', bufname(getqflist()[1].bufnr))
3977 au! BufRead Xtest2.txt
3978
3979 " Test 2:
3980 " When searching for a pattern using :vimgrep, if the quickfix list is
3981 " freed, then a error should be given.
3982 silent! %bwipe!
3983 call setqflist([], 'f')
3984 autocmd BufRead Xtest2.txt for i in range(10) | cexpr '' | endfor
3985 call assert_fails('vimgrep stars Xtest*.txt', 'E925:')
3986 au! BufRead Xtest2.txt
3987
3988 " Test 3:
3989 " When searching for a pattern using :lvimgrep, if the location list is
3990 " freed, then the command should error out.
3991 silent! %bwipe!
3992 let g:save_winid = win_getid()
3993 autocmd BufRead Xtest2.txt call setloclist(g:save_winid, [], 'f')
3994 call assert_fails('lvimgrep stars Xtest*.txt', 'E926:')
3995 au! BufRead Xtest2.txt
3996
3997 call delete('Xtest1.txt')
3998 call delete('Xtest2.txt')
3999 call setqflist([], 'f')
4000endfunc
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004001
Bram Moolenaarf9ae1542019-11-18 22:02:16 +01004002" Test for an autocmd changing the current directory when running vimgrep
4003func Xvimgrep_autocmd_cd(cchar)
4004 call s:setup_commands(a:cchar)
4005
4006 %bwipe
4007 let save_cwd = getcwd()
4008
4009 augroup QF_Test
4010 au!
4011 autocmd BufRead * silent cd %:p:h
4012 augroup END
4013
4014 10Xvimgrep /vim/ Xdir/**
4015 let l = g:Xgetlist()
4016 call assert_equal('f1.txt', bufname(l[0].bufnr))
4017 call assert_equal('f2.txt', fnamemodify(bufname(l[2].bufnr), ':t'))
4018
4019 augroup QF_Test
4020 au!
4021 augroup END
4022
4023 exe 'cd ' . save_cwd
4024endfunc
4025
4026func Test_vimgrep_autocmd_cd()
4027 call mkdir('Xdir/a', 'p')
4028 call mkdir('Xdir/b', 'p')
4029 call writefile(['a_L1_vim', 'a_L2_vim'], 'Xdir/a/f1.txt')
4030 call writefile(['b_L1_vim', 'b_L2_vim'], 'Xdir/b/f2.txt')
4031 call Xvimgrep_autocmd_cd('c')
4032 call Xvimgrep_autocmd_cd('l')
4033 %bwipe
4034 call delete('Xdir', 'rf')
4035endfunc
4036
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004037" The following test used to crash Vim
4038func Test_lhelpgrep_autocmd()
4039 lhelpgrep quickfix
4040 autocmd QuickFixCmdPost * call setloclist(0, [], 'f')
4041 lhelpgrep buffer
4042 call assert_equal('help', &filetype)
4043 call assert_equal(0, getloclist(0, {'nr' : '$'}).nr)
4044 lhelpgrep tabpage
4045 call assert_equal('help', &filetype)
4046 call assert_equal(1, getloclist(0, {'nr' : '$'}).nr)
4047 au! QuickFixCmdPost
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004048
4049 new | only
4050 augroup QF_Test
4051 au!
4052 au BufEnter * call setqflist([], 'f')
4053 augroup END
4054 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaardbfa7952020-11-02 20:04:22 +01004055 " run the test with a help window already open
4056 help
4057 wincmd w
4058 call assert_fails('helpgrep quickfix', 'E925:')
Bram Moolenaarb6f14802018-10-21 18:47:43 +02004059 augroup QF_Test
4060 au! BufEnter
4061 augroup END
4062
4063 new | only
4064 augroup QF_Test
4065 au!
4066 au BufEnter * call setqflist([], 'r')
4067 augroup END
4068 call assert_fails('helpgrep quickfix', 'E925:')
4069 augroup QF_Test
4070 au! BufEnter
4071 augroup END
4072
4073 new | only
4074 augroup QF_Test
4075 au!
4076 au BufEnter * call setloclist(0, [], 'r')
4077 augroup END
4078 call assert_fails('lhelpgrep quickfix', 'E926:')
4079 augroup QF_Test
4080 au! BufEnter
4081 augroup END
4082
Bram Moolenaar3b9474b2018-04-23 21:29:48 +02004083 new | only
4084endfunc
Bram Moolenaara796d462018-05-01 14:30:36 +02004085
4086" Test for shortening/simplifying the file name when opening the
4087" quickfix window or when displaying the quickfix list
4088func Test_shorten_fname()
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02004089 CheckUnix
Bram Moolenaara796d462018-05-01 14:30:36 +02004090 %bwipe
4091 " Create a quickfix list with a absolute path filename
4092 let fname = getcwd() . '/test_quickfix.vim'
4093 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4094 call assert_equal(fname, bufname('test_quickfix.vim'))
4095 " Opening the quickfix window should simplify the file path
4096 cwindow
4097 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
4098 cclose
4099 %bwipe
4100 " Create a quickfix list with a absolute path filename
4101 call setqflist([], ' ', {'lines':[fname . ":20:Line20"], 'efm':'%f:%l:%m'})
4102 call assert_equal(fname, bufname('test_quickfix.vim'))
4103 " Displaying the quickfix list should simplify the file path
4104 silent! clist
4105 call assert_equal('test_quickfix.vim', bufname('test_quickfix.vim'))
Bram Moolenaar8ec92c92020-09-29 22:47:03 +02004106 " Add a few entries for the same file with different paths and check whether
4107 " the buffer name is shortened
4108 %bwipe
4109 call setqflist([], 'f')
4110 call setqflist([{'filename' : 'test_quickfix.vim', 'lnum' : 10},
4111 \ {'filename' : '../testdir/test_quickfix.vim', 'lnum' : 20},
4112 \ {'filename' : fname, 'lnum' : 30}], ' ')
4113 copen
4114 call assert_equal(['test_quickfix.vim|10| ',
4115 \ 'test_quickfix.vim|20| ',
4116 \ 'test_quickfix.vim|30| '], getline(1, '$'))
4117 cclose
Bram Moolenaara796d462018-05-01 14:30:36 +02004118endfunc
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004119
4120" Quickfix title tests
4121" In the below tests, 'exe "cmd"' is used to invoke the quickfix commands.
4122" Otherwise due to indentation, the title is set with spaces at the beginning
4123" of the command.
4124func Test_qftitle()
4125 call writefile(["F1:1:Line1"], 'Xerr')
4126
4127 " :cexpr
4128 exe "cexpr readfile('Xerr')"
4129 call assert_equal(":cexpr readfile('Xerr')", getqflist({'title' : 1}).title)
4130
4131 " :cgetexpr
4132 exe "cgetexpr readfile('Xerr')"
4133 call assert_equal(":cgetexpr readfile('Xerr')",
4134 \ getqflist({'title' : 1}).title)
4135
4136 " :caddexpr
4137 call setqflist([], 'f')
4138 exe "caddexpr readfile('Xerr')"
4139 call assert_equal(":caddexpr readfile('Xerr')",
4140 \ getqflist({'title' : 1}).title)
4141
4142 " :cbuffer
4143 new Xerr
4144 exe "cbuffer"
4145 call assert_equal(':cbuffer (Xerr)', getqflist({'title' : 1}).title)
4146
4147 " :cgetbuffer
4148 edit Xerr
4149 exe "cgetbuffer"
4150 call assert_equal(':cgetbuffer (Xerr)', getqflist({'title' : 1}).title)
4151
4152 " :caddbuffer
4153 call setqflist([], 'f')
4154 edit Xerr
4155 exe "caddbuffer"
4156 call assert_equal(':caddbuffer (Xerr)', getqflist({'title' : 1}).title)
4157
4158 " :cfile
4159 exe "cfile Xerr"
4160 call assert_equal(':cfile Xerr', getqflist({'title' : 1}).title)
4161
4162 " :cgetfile
4163 exe "cgetfile Xerr"
4164 call assert_equal(':cgetfile Xerr', getqflist({'title' : 1}).title)
4165
4166 " :caddfile
4167 call setqflist([], 'f')
4168 exe "caddfile Xerr"
4169 call assert_equal(':caddfile Xerr', getqflist({'title' : 1}).title)
4170
4171 " :grep
4172 set grepprg=internal
4173 exe "grep F1 Xerr"
4174 call assert_equal(':grep F1 Xerr', getqflist({'title' : 1}).title)
4175
4176 " :grepadd
4177 call setqflist([], 'f')
4178 exe "grepadd F1 Xerr"
4179 call assert_equal(':grepadd F1 Xerr', getqflist({'title' : 1}).title)
4180 set grepprg&vim
4181
4182 " :vimgrep
4183 exe "vimgrep F1 Xerr"
4184 call assert_equal(':vimgrep F1 Xerr', getqflist({'title' : 1}).title)
4185
4186 " :vimgrepadd
4187 call setqflist([], 'f')
4188 exe "vimgrepadd F1 Xerr"
4189 call assert_equal(':vimgrepadd F1 Xerr', getqflist({'title' : 1}).title)
4190
4191 call setqflist(['F1:10:L10'], ' ')
4192 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4193
4194 call setqflist([], 'f')
4195 call setqflist(['F1:10:L10'], 'a')
4196 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4197
4198 call setqflist([], 'f')
4199 call setqflist(['F1:10:L10'], 'r')
4200 call assert_equal(':setqflist()', getqflist({'title' : 1}).title)
4201
4202 close
4203 call delete('Xerr')
4204
4205 call setqflist([], ' ', {'title' : 'Errors'})
4206 copen
4207 call assert_equal('Errors', w:quickfix_title)
4208 call setqflist([], 'r', {'items' : [{'filename' : 'a.c', 'lnum' : 10}]})
4209 call assert_equal('Errors', w:quickfix_title)
4210 cclose
Bram Moolenaar530bed92020-12-16 21:02:56 +01004211
4212 " Switching to another quickfix list in one tab page should update the
4213 " quickfix window title and statusline in all the other tab pages also
4214 call setqflist([], 'f')
4215 %bw!
4216 cgetexpr ['file_one:1:1: error in the first quickfix list']
4217 call setqflist([], 'a', {'title': 'first quickfix list'})
4218 cgetexpr ['file_two:2:1: error in the second quickfix list']
4219 call setqflist([], 'a', {'title': 'second quickfix list'})
4220 copen
4221 wincmd t
4222 tabnew two
4223 copen
4224 wincmd t
4225 colder
4226 call assert_equal('first quickfix list', gettabwinvar(1, 2, 'quickfix_title'))
4227 call assert_equal('first quickfix list', gettabwinvar(2, 2, 'quickfix_title'))
4228 call assert_equal(1, tabpagewinnr(1))
4229 call assert_equal(1, tabpagewinnr(2))
4230 tabnew
4231 call setqflist([], 'a', {'title': 'new quickfix title'})
4232 call assert_equal('new quickfix title', gettabwinvar(1, 2, 'quickfix_title'))
4233 call assert_equal('new quickfix title', gettabwinvar(2, 2, 'quickfix_title'))
4234 %bw!
Bram Moolenaar8b62e312018-05-13 15:29:04 +02004235endfunc
Bram Moolenaar600323b2018-06-16 22:16:47 +02004236
4237func Test_lbuffer_with_bwipe()
4238 new
4239 new
4240 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004241 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * bwipe
Bram Moolenaar600323b2018-06-16 22:16:47 +02004242 augroup END
4243 lbuffer
4244 augroup nasty
4245 au!
4246 augroup END
4247endfunc
Bram Moolenaar0366c012018-06-18 20:52:13 +02004248
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004249" Test for an autocmd freeing the quickfix/location list when cexpr/lexpr is
4250" running
4251func Xexpr_acmd_freelist(cchar)
4252 call s:setup_commands(a:cchar)
4253
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004254 " This was using freed memory (but with what events?)
Bram Moolenaar0366c012018-06-18 20:52:13 +02004255 augroup nasty
Bram Moolenaar9a046fd2021-01-28 13:47:59 +01004256 au QuickFixCmdPre,QuickFixCmdPost,BufEnter,BufLeave * call g:Xsetlist([], 'f')
Bram Moolenaar0366c012018-06-18 20:52:13 +02004257 augroup END
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004258 Xexpr "x"
Bram Moolenaar0366c012018-06-18 20:52:13 +02004259 augroup nasty
4260 au!
4261 augroup END
4262endfunc
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004263
4264func Test_cexpr_acmd_freelist()
4265 call Xexpr_acmd_freelist('c')
4266 call Xexpr_acmd_freelist('l')
4267endfunc
4268
4269" Test for commands that create a new quickfix/location list and jump to the
4270" first error automatically.
4271func Xjumpto_first_error_test(cchar)
4272 call s:setup_commands(a:cchar)
4273
4274 call s:create_test_file('Xtestfile1')
4275 call s:create_test_file('Xtestfile2')
4276 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4277
4278 " Test for cexpr/lexpr
4279 enew
4280 Xexpr l
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004281 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004282 call assert_equal(2, line('.'))
4283
4284 " Test for cfile/lfile
4285 enew
4286 call writefile(l, 'Xerr')
4287 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004288 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004289 call assert_equal(2, line('.'))
4290
4291 " Test for cbuffer/lbuffer
4292 edit Xerr
4293 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004294 call assert_equal('Xtestfile1', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004295 call assert_equal(2, line('.'))
4296
4297 call delete('Xerr')
4298 call delete('Xtestfile1')
4299 call delete('Xtestfile2')
4300endfunc
4301
4302func Test_jumpto_first_error()
4303 call Xjumpto_first_error_test('c')
4304 call Xjumpto_first_error_test('l')
4305endfunc
4306
4307" Test for a quickfix autocmd changing the quickfix/location list before
4308" jumping to the first error in the new list.
4309func Xautocmd_changelist(cchar)
4310 call s:setup_commands(a:cchar)
4311
4312 " Test for cfile/lfile
4313 call s:create_test_file('Xtestfile1')
4314 call s:create_test_file('Xtestfile2')
4315 Xexpr 'Xtestfile1:2:Line2'
4316 autocmd QuickFixCmdPost * Xolder
4317 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4318 Xfile Xerr
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004319 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004320 call assert_equal(4, line('.'))
4321 autocmd! QuickFixCmdPost
4322
4323 " Test for cbuffer/lbuffer
4324 call g:Xsetlist([], 'f')
4325 Xexpr 'Xtestfile1:2:Line2'
4326 autocmd QuickFixCmdPost * Xolder
4327 call writefile(['Xtestfile2:4:Line4'], 'Xerr')
4328 edit Xerr
4329 Xbuffer
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004330 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004331 call assert_equal(4, line('.'))
4332 autocmd! QuickFixCmdPost
4333
4334 " Test for cexpr/lexpr
4335 call g:Xsetlist([], 'f')
4336 Xexpr 'Xtestfile1:2:Line2'
4337 autocmd QuickFixCmdPost * Xolder
4338 Xexpr 'Xtestfile2:4:Line4'
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004339 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004340 call assert_equal(4, line('.'))
4341 autocmd! QuickFixCmdPost
4342
Bram Moolenaar851332e2018-07-03 19:16:00 +02004343 " The grepprg may not be set on non-Unix systems
4344 if has('unix')
4345 " Test for grep/lgrep
4346 call g:Xsetlist([], 'f')
4347 Xexpr 'Xtestfile1:2:Line2'
4348 autocmd QuickFixCmdPost * Xolder
4349 silent Xgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004350 call assert_equal('Xtestfile2', @%)
Bram Moolenaar851332e2018-07-03 19:16:00 +02004351 call assert_equal(5, line('.'))
4352 autocmd! QuickFixCmdPost
4353 endif
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004354
4355 " Test for vimgrep/lvimgrep
4356 call g:Xsetlist([], 'f')
4357 Xexpr 'Xtestfile1:2:Line2'
4358 autocmd QuickFixCmdPost * Xolder
4359 silent Xvimgrep Line5 Xtestfile2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004360 call assert_equal('Xtestfile2', @%)
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004361 call assert_equal(5, line('.'))
4362 autocmd! QuickFixCmdPost
4363
Bram Moolenaar3f347e42018-08-09 21:19:20 +02004364 " Test for autocommands clearing the quickfix list before jumping to the
4365 " first error. This should not result in an error
4366 autocmd QuickFixCmdPost * call g:Xsetlist([], 'r')
4367 let v:errmsg = ''
4368 " Test for cfile/lfile
4369 Xfile Xerr
4370 call assert_true(v:errmsg !~# 'E42:')
4371 " Test for cbuffer/lbuffer
4372 edit Xerr
4373 Xbuffer
4374 call assert_true(v:errmsg !~# 'E42:')
4375 " Test for cexpr/lexpr
4376 Xexpr 'Xtestfile2:4:Line4'
4377 call assert_true(v:errmsg !~# 'E42:')
4378 " Test for grep/lgrep
4379 " The grepprg may not be set on non-Unix systems
4380 if has('unix')
4381 silent Xgrep Line5 Xtestfile2
4382 call assert_true(v:errmsg !~# 'E42:')
4383 endif
4384 " Test for vimgrep/lvimgrep
4385 call assert_fails('silent Xvimgrep Line5 Xtestfile2', 'E480:')
4386 autocmd! QuickFixCmdPost
4387
Bram Moolenaar531b9a32018-07-03 16:54:23 +02004388 call delete('Xerr')
4389 call delete('Xtestfile1')
4390 call delete('Xtestfile2')
4391endfunc
4392
4393func Test_autocmd_changelist()
4394 call Xautocmd_changelist('c')
4395 call Xautocmd_changelist('l')
4396endfunc
Bram Moolenaar4cde86c2018-07-08 16:01:08 +02004397
4398" Tests for the ':filter /pat/ clist' command
4399func Test_filter_clist()
4400 cexpr ['Xfile1:10:10:Line 10', 'Xfile2:15:15:Line 15']
4401 call assert_equal([' 2 Xfile2:15 col 15: Line 15'],
4402 \ split(execute('filter /Line 15/ clist'), "\n"))
4403 call assert_equal([' 1 Xfile1:10 col 10: Line 10'],
4404 \ split(execute('filter /Xfile1/ clist'), "\n"))
4405 call assert_equal([], split(execute('filter /abc/ clist'), "\n"))
4406
4407 call setqflist([{'module' : 'abc', 'pattern' : 'pat1'},
4408 \ {'module' : 'pqr', 'pattern' : 'pat2'}], ' ')
4409 call assert_equal([' 2 pqr:pat2: '],
4410 \ split(execute('filter /pqr/ clist'), "\n"))
4411 call assert_equal([' 1 abc:pat1: '],
4412 \ split(execute('filter /pat1/ clist'), "\n"))
4413endfunc
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004414
4415" Tests for the "CTRL-W <CR>" command.
4416func Xview_result_split_tests(cchar)
4417 call s:setup_commands(a:cchar)
4418
4419 " Test that "CTRL-W <CR>" in a qf/ll window fails with empty list.
4420 call g:Xsetlist([])
4421 Xopen
4422 let l:win_count = winnr('$')
Bram Moolenaare2e40752020-09-04 21:18:46 +02004423 call assert_fails('execute "normal! \<C-W>\<CR>"', 'E42:')
Bram Moolenaar0a08c632018-07-25 22:36:52 +02004424 call assert_equal(l:win_count, winnr('$'))
4425 Xclose
4426endfunc
4427
4428func Test_view_result_split()
4429 call Xview_result_split_tests('c')
4430 call Xview_result_split_tests('l')
4431endfunc
Bram Moolenaar2dfcef42018-08-15 22:29:51 +02004432
4433" Test that :cc sets curswant
4434func Test_curswant()
4435 helpgrep quickfix
4436 normal! llll
4437 1cc
4438 call assert_equal(getcurpos()[4], virtcol('.'))
4439 cclose | helpclose
4440endfunc
Bram Moolenaarb2443732018-11-11 22:50:27 +01004441
4442" Test for opening a file from the quickfix window using CTRL-W <Enter>
4443" doesn't leave an empty buffer around.
4444func Test_splitview()
4445 call s:create_test_file('Xtestfile1')
4446 call s:create_test_file('Xtestfile2')
4447 new | only
4448 let last_bufnr = bufnr('Test_sv_1', 1)
4449 let l = ['Xtestfile1:2:Line2', 'Xtestfile2:4:Line4']
4450 cgetexpr l
4451 copen
4452 let numbufs = len(getbufinfo())
4453 exe "normal \<C-W>\<CR>"
4454 copen
4455 exe "normal j\<C-W>\<CR>"
4456 " Make sure new empty buffers are not created
4457 call assert_equal(numbufs, len(getbufinfo()))
4458 " Creating a new buffer should use the next available buffer number
4459 call assert_equal(last_bufnr + 4, bufnr("Test_sv_2", 1))
4460 bwipe Test_sv_1
4461 bwipe Test_sv_2
4462 new | only
4463
4464 " When split opening files from location list window, make sure that two
4465 " windows doesn't refer to the same location list
4466 lgetexpr l
4467 let locid = getloclist(0, {'id' : 0}).id
4468 lopen
4469 exe "normal \<C-W>\<CR>"
4470 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4471 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4472 new | only
4473
4474 " When split opening files from a helpgrep location list window, a new help
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004475 " window should be opened with a copy of the location list.
Bram Moolenaarb2443732018-11-11 22:50:27 +01004476 lhelpgrep window
4477 let locid = getloclist(0, {'id' : 0}).id
4478 lwindow
4479 exe "normal j\<C-W>\<CR>"
4480 call assert_notequal(locid, getloclist(0, {'id' : 0}).id)
4481 call assert_equal(0, getloclist(0, {'winid' : 0}).winid)
4482 new | only
4483
Bram Moolenaar406cd902020-02-18 21:54:41 +01004484 " Using :split or :vsplit from a quickfix window should behave like a :new
4485 " or a :vnew command
4486 copen
4487 split
4488 call assert_equal(3, winnr('$'))
4489 let l = getwininfo()
4490 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4491 close
4492 copen
4493 vsplit
4494 let l = getwininfo()
4495 call assert_equal([0, 0, 1], [l[0].quickfix, l[1].quickfix, l[2].quickfix])
4496 new | only
4497
Bram Moolenaarb2443732018-11-11 22:50:27 +01004498 call delete('Xtestfile1')
4499 call delete('Xtestfile2')
4500endfunc
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004501
4502" Test for parsing entries using visual screen column
4503func Test_viscol()
4504 enew
4505 call writefile(["Col1\tCol2\tCol3"], 'Xfile1')
4506 edit Xfile1
4507
4508 " Use byte offset for column number
4509 set efm&
4510 cexpr "Xfile1:1:5:XX\nXfile1:1:9:YY\nXfile1:1:20:ZZ"
4511 call assert_equal([5, 8], [col('.'), virtcol('.')])
4512 cnext
4513 call assert_equal([9, 12], [col('.'), virtcol('.')])
4514 cnext
4515 call assert_equal([14, 20], [col('.'), virtcol('.')])
4516
4517 " Use screen column offset for column number
4518 set efm=%f:%l:%v:%m
4519 cexpr "Xfile1:1:8:XX\nXfile1:1:12:YY\nXfile1:1:20:ZZ"
4520 call assert_equal([5, 8], [col('.'), virtcol('.')])
4521 cnext
4522 call assert_equal([9, 12], [col('.'), virtcol('.')])
4523 cnext
4524 call assert_equal([14, 20], [col('.'), virtcol('.')])
4525 cexpr "Xfile1:1:6:XX\nXfile1:1:15:YY\nXfile1:1:24:ZZ"
4526 call assert_equal([5, 8], [col('.'), virtcol('.')])
4527 cnext
4528 call assert_equal([10, 16], [col('.'), virtcol('.')])
4529 cnext
4530 call assert_equal([14, 20], [col('.'), virtcol('.')])
4531
4532 enew
4533 call writefile(["Col1\täü\töß\tCol4"], 'Xfile1')
4534
4535 " Use byte offset for column number
4536 set efm&
4537 cexpr "Xfile1:1:8:XX\nXfile1:1:11:YY\nXfile1:1:16:ZZ"
4538 call assert_equal([8, 10], [col('.'), virtcol('.')])
4539 cnext
4540 call assert_equal([11, 17], [col('.'), virtcol('.')])
4541 cnext
4542 call assert_equal([16, 25], [col('.'), virtcol('.')])
4543
4544 " Use screen column offset for column number
4545 set efm=%f:%l:%v:%m
4546 cexpr "Xfile1:1:10:XX\nXfile1:1:17:YY\nXfile1:1:25:ZZ"
4547 call assert_equal([8, 10], [col('.'), virtcol('.')])
4548 cnext
4549 call assert_equal([11, 17], [col('.'), virtcol('.')])
4550 cnext
4551 call assert_equal([16, 25], [col('.'), virtcol('.')])
4552
Bram Moolenaarc95940c2020-10-20 14:59:12 +02004553 " Use screen column number with a multi-line error message
4554 enew
4555 call writefile(["à test"], 'Xfile1')
4556 set efm=%E===\ %f\ ===,%C%l:%v,%Z%m
4557 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4558 call assert_equal('Xfile1', @%)
4559 call assert_equal([0, 1, 4, 0], getpos('.'))
4560
4561 " Repeat previous test with byte offset %c: ensure that fix to issue #7145
4562 " does not break this
4563 set efm=%E===\ %f\ ===,%C%l:%c,%Z%m
4564 cexpr ["=== Xfile1 ===", "1:3", "errormsg"]
4565 call assert_equal('Xfile1', @%)
4566 call assert_equal([0, 1, 3, 0], getpos('.'))
4567
Bram Moolenaarc45eb772019-01-31 14:27:04 +01004568 enew | only
4569 set efm&
4570 call delete('Xfile1')
4571endfunc
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004572
4573" Test for the quickfix window buffer
4574func Xqfbuf_test(cchar)
4575 call s:setup_commands(a:cchar)
4576
4577 " Quickfix buffer should be reused across closing and opening a quickfix
4578 " window
4579 Xexpr "F1:10:Line10"
4580 Xopen
4581 let qfbnum = bufnr('')
4582 Xclose
4583 " Even after the quickfix window is closed, the buffer should be loaded
4584 call assert_true(bufloaded(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004585 call assert_true(qfbnum, g:Xgetlist({'qfbufnr' : 0}).qfbufnr)
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004586 Xopen
4587 " Buffer should be reused when opening the window again
4588 call assert_equal(qfbnum, bufnr(''))
4589 Xclose
4590
4591 if a:cchar == 'l'
4592 %bwipe
4593 " For a location list, when both the file window and the location list
4594 " window for the list are closed, then the buffer should be freed.
4595 new | only
4596 lexpr "F1:10:Line10"
4597 let wid = win_getid()
4598 lopen
4599 let qfbnum = bufnr('')
4600 call assert_match(qfbnum . ' %a- "\[Location List]"', execute('ls'))
4601 close
4602 " When the location list window is closed, the buffer name should not
4603 " change to 'Quickfix List'
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004604 call assert_match(qfbnum . 'u h- "\[Location List]"', execute('ls!'))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004605 call assert_true(bufloaded(qfbnum))
4606
Bram Moolenaard82a81c2019-03-02 07:57:18 +01004607 " After deleting a location list buffer using ":bdelete", opening the
4608 " location list window should mark the buffer as a location list buffer.
4609 exe "bdelete " . qfbnum
4610 lopen
4611 call assert_equal("quickfix", &buftype)
4612 call assert_equal(1, getwininfo(win_getid(winnr()))[0].loclist)
4613 call assert_equal(wid, getloclist(0, {'filewinid' : 0}).filewinid)
4614 call assert_false(&swapfile)
4615 lclose
4616
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004617 " When the location list is cleared for the window, the buffer should be
4618 " removed
4619 call setloclist(0, [], 'f')
4620 call assert_false(bufexists(qfbnum))
Bram Moolenaar647e24b2019-03-17 16:39:46 +01004621 call assert_equal(0, getloclist(0, {'qfbufnr' : 0}).qfbufnr)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004622
4623 " When the location list is freed with the location list window open, the
4624 " location list buffer should not be lost. It should be reused when the
4625 " location list is again populated.
4626 lexpr "F1:10:Line10"
4627 lopen
4628 let wid = win_getid()
4629 let qfbnum = bufnr('')
4630 wincmd p
4631 call setloclist(0, [], 'f')
4632 lexpr "F1:10:Line10"
4633 lopen
4634 call assert_equal(wid, win_getid())
4635 call assert_equal(qfbnum, bufnr(''))
4636 lclose
4637
4638 " When the window with the location list is closed, the buffer should be
4639 " removed
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004640 new | only
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004641 call assert_false(bufexists(qfbnum))
Bram Moolenaaree8188f2019-02-05 21:23:04 +01004642 endif
4643endfunc
4644
4645func Test_qfbuf()
4646 call Xqfbuf_test('c')
4647 call Xqfbuf_test('l')
4648endfunc
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004649
4650" If there is an autocmd to use only one window, then opening the location
4651" list window used to crash Vim.
4652func Test_winonly_autocmd()
4653 call s:create_test_file('Xtest1')
4654 " Autocmd to show only one Vim window at a time
4655 autocmd WinEnter * only
4656 new
4657 " Load the location list
4658 lexpr "Xtest1:5:Line5\nXtest1:10:Line10\nXtest1:15:Line15"
4659 let loclistid = getloclist(0, {'id' : 0}).id
4660 " Open the location list window. Only this window will be shown and the file
4661 " window is closed.
4662 lopen
4663 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
4664 " Jump to an entry in the location list and make sure that the cursor is
4665 " positioned correctly.
4666 ll 3
4667 call assert_equal(loclistid, getloclist(0, {'id' : 0}).id)
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004668 call assert_equal('Xtest1', @%)
Bram Moolenaareeb1b9c2019-02-10 22:59:04 +01004669 call assert_equal(15, line('.'))
4670 " Cleanup
4671 autocmd! WinEnter
4672 new | only
4673 call delete('Xtest1')
4674endfunc
Bram Moolenaar39803d82019-04-07 12:04:51 +02004675
4676" Test to make sure that an empty quickfix buffer is not reused for loading
4677" a normal buffer.
4678func Test_empty_qfbuf()
4679 enew | only
4680 call writefile(["Test"], 'Xfile1')
4681 call setqflist([], 'f')
4682 copen | only
4683 let qfbuf = bufnr('')
4684 edit Xfile1
4685 call assert_notequal(qfbuf, bufnr(''))
4686 enew
4687 call delete('Xfile1')
4688endfunc
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004689
4690" Test for the :cbelow, :cabove, :lbelow and :labove commands.
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004691" And for the :cafter, :cbefore, :lafter and :lbefore commands.
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004692func Xtest_below(cchar)
4693 call s:setup_commands(a:cchar)
4694
4695 " No quickfix/location list
4696 call assert_fails('Xbelow', 'E42:')
4697 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004698 call assert_fails('Xbefore', 'E42:')
4699 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004700
4701 " Empty quickfix/location list
4702 call g:Xsetlist([])
4703 call assert_fails('Xbelow', 'E42:')
4704 call assert_fails('Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004705 call assert_fails('Xbefore', 'E42:')
4706 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004707
4708 call s:create_test_file('X1')
4709 call s:create_test_file('X2')
4710 call s:create_test_file('X3')
4711 call s:create_test_file('X4')
4712
4713 " Invalid entries
4714 edit X1
4715 call g:Xsetlist(["E1", "E2"])
4716 call assert_fails('Xbelow', 'E42:')
4717 call assert_fails('Xabove', 'E42:')
4718 call assert_fails('3Xbelow', 'E42:')
4719 call assert_fails('4Xabove', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004720 call assert_fails('Xbefore', 'E42:')
4721 call assert_fails('Xafter', 'E42:')
4722 call assert_fails('3Xbefore', 'E42:')
4723 call assert_fails('4Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004724
4725 " Test the commands with various arguments
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004726 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 +02004727 edit +7 X2
4728 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004729 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004730 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004731 normal 7G
4732 Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004733 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004734 call assert_fails('Xbefore', 'E553:')
4735
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004736 normal 2j
4737 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004738 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004739 normal 7G
4740 Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004741 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004742
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004743 " Last error in this file
4744 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004745 call assert_equal(['X2', 15], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004746 call assert_fails('Xbelow', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004747 normal gg
4748 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004749 call assert_equal(['X2', 15, 4], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004750 call assert_fails('Xafter', 'E553:')
4751
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004752 " First error in this file
4753 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004754 call assert_equal(['X2', 5], [@%, line('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004755 call assert_fails('Xabove', 'E553:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004756 normal G
4757 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004758 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004759 call assert_fails('Xbefore', 'E553:')
4760
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004761 normal gg
4762 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004763 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004764 normal gg
4765 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004766 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004767
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004768 normal G
4769 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004770 call assert_equal(['X2', 10], [@%, line('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004771 normal G
4772 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004773 call assert_equal(['X2', 10, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004774
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004775 edit X4
4776 call assert_fails('Xabove', 'E42:')
4777 call assert_fails('Xbelow', 'E42:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004778 call assert_fails('Xbefore', 'E42:')
4779 call assert_fails('Xafter', 'E42:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004780 if a:cchar == 'l'
4781 " If a buffer has location list entries from some other window but not
4782 " from the current window, then the commands should fail.
4783 edit X1 | split | call setloclist(0, [], 'f')
4784 call assert_fails('Xabove', 'E776:')
4785 call assert_fails('Xbelow', 'E776:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004786 call assert_fails('Xbefore', 'E776:')
4787 call assert_fails('Xafter', 'E776:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004788 close
4789 endif
4790
4791 " Test for lines with multiple quickfix entries
4792 Xexpr ["X1:5:L5", "X2:5:1:L5_1", "X2:5:2:L5_2", "X2:5:3:L5_3",
4793 \ "X2:10:1:L10_1", "X2:10:2:L10_2", "X2:10:3:L10_3",
4794 \ "X2:15:1:L15_1", "X2:15:2:L15_2", "X2:15:3:L15_3", "X3:3:L3"]
4795 edit +1 X2
4796 Xbelow 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004797 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004798 normal 1G
4799 Xafter 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004800 call assert_equal(['X2', 5, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004801
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004802 normal gg
4803 Xbelow 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004804 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004805 normal gg
4806 Xafter 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004807 call assert_equal(['X2', 15, 3], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004808
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004809 normal G
4810 Xabove 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004811 call assert_equal(['X2', 10, 1], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004812 normal G
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004813 Xbefore 2
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004814 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004815
4816 normal G
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004817 Xabove 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004818 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004819 normal G
4820 Xbefore 99
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004821 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004822
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004823 normal 10G
4824 Xabove
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004825 call assert_equal(['X2', 5, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004826 normal 10G$
4827 2Xbefore
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004828 call assert_equal(['X2', 10, 2], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004829
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004830 normal 10G
4831 Xbelow
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004832 call assert_equal(['X2', 15, 1], [@%, line('.'), col('.')])
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004833 normal 9G
4834 5Xafter
Bram Moolenaarbdd2c292020-06-22 21:34:30 +02004835 call assert_equal(['X2', 15, 2], [@%, line('.'), col('.')])
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004836
4837 " Invalid range
4838 if a:cchar == 'c'
Bram Moolenaar25190db2019-05-04 15:05:28 +02004839 call assert_fails('-2cbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004840 call assert_fails('-2cafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004841 else
Bram Moolenaar25190db2019-05-04 15:05:28 +02004842 call assert_fails('-2lbelow', 'E16:')
Bram Moolenaarcf6a55c2019-05-05 15:02:30 +02004843 call assert_fails('-2lafter', 'E16:')
Bram Moolenaar3ff33112019-05-03 21:56:35 +02004844 endif
4845
4846 call delete('X1')
4847 call delete('X2')
4848 call delete('X3')
4849 call delete('X4')
4850endfunc
4851
4852func Test_cbelow()
4853 call Xtest_below('c')
4854 call Xtest_below('l')
4855endfunc
Bram Moolenaar25190db2019-05-04 15:05:28 +02004856
4857func Test_quickfix_count()
4858 let commands = [
4859 \ 'cNext',
4860 \ 'cNfile',
4861 \ 'cabove',
4862 \ 'cbelow',
4863 \ 'cfirst',
4864 \ 'clast',
4865 \ 'cnewer',
4866 \ 'cnext',
4867 \ 'cnfile',
4868 \ 'colder',
4869 \ 'cprevious',
4870 \ 'crewind',
4871 \
4872 \ 'lNext',
4873 \ 'lNfile',
4874 \ 'labove',
4875 \ 'lbelow',
4876 \ 'lfirst',
4877 \ 'llast',
4878 \ 'lnewer',
4879 \ 'lnext',
4880 \ 'lnfile',
4881 \ 'lolder',
4882 \ 'lprevious',
4883 \ 'lrewind',
4884 \ ]
4885 for cmd in commands
4886 call assert_fails('-1' .. cmd, 'E16:')
4887 call assert_fails('.' .. cmd, 'E16:')
4888 call assert_fails('%' .. cmd, 'E16:')
4889 call assert_fails('$' .. cmd, 'E16:')
4890 endfor
4891endfunc
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02004892
4893" Test for aborting quickfix commands using QuickFixCmdPre
4894func Xtest_qfcmd_abort(cchar)
4895 call s:setup_commands(a:cchar)
4896
4897 call g:Xsetlist([], 'f')
4898
4899 " cexpr/lexpr
4900 let e = ''
4901 try
4902 Xexpr ["F1:10:Line10", "F2:20:Line20"]
4903 catch /.*/
4904 let e = v:exception
4905 endtry
4906 call assert_equal('AbortCmd', e)
4907 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4908
4909 " cfile/lfile
4910 call writefile(["F1:10:Line10", "F2:20:Line20"], 'Xfile1')
4911 let e = ''
4912 try
4913 Xfile Xfile1
4914 catch /.*/
4915 let e = v:exception
4916 endtry
4917 call assert_equal('AbortCmd', e)
4918 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4919 call delete('Xfile1')
4920
4921 " cgetbuffer/lgetbuffer
4922 enew!
4923 call append(0, ["F1:10:Line10", "F2:20:Line20"])
4924 let e = ''
4925 try
4926 Xgetbuffer
4927 catch /.*/
4928 let e = v:exception
4929 endtry
4930 call assert_equal('AbortCmd', e)
4931 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4932 enew!
4933
4934 " vimgrep/lvimgrep
4935 let e = ''
4936 try
4937 Xvimgrep /func/ test_quickfix.vim
4938 catch /.*/
4939 let e = v:exception
4940 endtry
4941 call assert_equal('AbortCmd', e)
4942 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4943
4944 " helpgrep/lhelpgrep
4945 let e = ''
4946 try
4947 Xhelpgrep quickfix
4948 catch /.*/
4949 let e = v:exception
4950 endtry
4951 call assert_equal('AbortCmd', e)
4952 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4953
4954 " grep/lgrep
4955 if has('unix')
4956 let e = ''
4957 try
4958 silent Xgrep func test_quickfix.vim
4959 catch /.*/
4960 let e = v:exception
4961 endtry
4962 call assert_equal('AbortCmd', e)
4963 call assert_equal(0, g:Xgetlist({'nr' : '$'}).nr)
4964 endif
4965endfunc
4966
4967func Test_qfcmd_abort()
4968 augroup QF_Test
4969 au!
4970 autocmd QuickFixCmdPre * throw "AbortCmd"
4971 augroup END
4972
4973 call Xtest_qfcmd_abort('c')
4974 call Xtest_qfcmd_abort('l')
4975
4976 augroup QF_Test
4977 au!
4978 augroup END
4979endfunc
4980
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01004981" Test for using a file in one of the parent directories.
4982func Test_search_in_dirstack()
4983 call mkdir('Xtestdir/a/b/c', 'p')
4984 let save_cwd = getcwd()
4985 call writefile(["X1_L1", "X1_L2"], 'Xtestdir/Xfile1')
4986 call writefile(["X2_L1", "X2_L2"], 'Xtestdir/a/Xfile2')
4987 call writefile(["X3_L1", "X3_L2"], 'Xtestdir/a/b/Xfile3')
4988 call writefile(["X4_L1", "X4_L2"], 'Xtestdir/a/b/c/Xfile4')
4989
4990 let lines = "Entering dir Xtestdir\n" .
4991 \ "Entering dir a\n" .
4992 \ "Entering dir b\n" .
4993 \ "Xfile2:2:X2_L2\n" .
4994 \ "Leaving dir a\n" .
4995 \ "Xfile1:2:X1_L2\n" .
4996 \ "Xfile3:1:X3_L1\n" .
4997 \ "Entering dir c\n" .
4998 \ "Xfile4:2:X4_L2\n" .
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01004999 \ "Leaving dir c\n"
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005000 set efm=%DEntering\ dir\ %f,%XLeaving\ dir\ %f,%f:%l:%m
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005001 cexpr lines .. "Leaving dir Xtestdir|\n" | let next = 1
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005002 call assert_equal(11, getqflist({'size' : 0}).size)
5003 call assert_equal(4, getqflist({'idx' : 0}).idx)
5004 call assert_equal('X2_L2', getline('.'))
Bram Moolenaar88a3e2b2019-12-06 21:11:39 +01005005 call assert_equal(1, next)
Bram Moolenaard8a8c4c2019-11-16 21:04:57 +01005006 cnext
5007 call assert_equal(6, getqflist({'idx' : 0}).idx)
5008 call assert_equal('X1_L2', getline('.'))
5009 cnext
5010 call assert_equal(7, getqflist({'idx' : 0}).idx)
5011 call assert_equal(1, line('$'))
5012 call assert_equal('', getline(1))
5013 cnext
5014 call assert_equal(9, getqflist({'idx' : 0}).idx)
5015 call assert_equal(1, line('$'))
5016 call assert_equal('', getline(1))
5017
5018 set efm&
5019 exe 'cd ' . save_cwd
5020 call delete('Xtestdir', 'rf')
5021endfunc
5022
Bram Moolenaar1860bde2020-01-06 21:47:21 +01005023" Test for :cquit
5024func Test_cquit()
5025 " Exit Vim with a non-zero value
5026 if RunVim([], ["cquit 7"], '')
5027 call assert_equal(7, v:shell_error)
5028 endif
5029
5030 if RunVim([], ["50cquit"], '')
5031 call assert_equal(50, v:shell_error)
5032 endif
5033
5034 " Exit Vim with default value
5035 if RunVim([], ["cquit"], '')
5036 call assert_equal(1, v:shell_error)
5037 endif
5038
5039 " Exit Vim with zero value
5040 if RunVim([], ["cquit 0"], '')
5041 call assert_equal(0, v:shell_error)
5042 endif
5043
5044 " Exit Vim with negative value
5045 call assert_fails('-3cquit', 'E16:')
5046endfunc
5047
Bram Moolenaar858ba062020-05-31 23:11:59 +02005048" Test for getting a specific item from a quickfix list
5049func Xtest_getqflist_by_idx(cchar)
5050 call s:setup_commands(a:cchar)
5051 " Empty list
5052 call assert_equal([], g:Xgetlist({'idx' : 1, 'items' : 0}).items)
5053 Xexpr ['F1:10:L10', 'F1:20:L20']
5054 let l = g:Xgetlist({'idx' : 2, 'items' : 0}).items
5055 call assert_equal(bufnr('F1'), l[0].bufnr)
5056 call assert_equal(20, l[0].lnum)
5057 call assert_equal('L20', l[0].text)
5058 call assert_equal([], g:Xgetlist({'idx' : -1, 'items' : 0}).items)
5059 call assert_equal([], g:Xgetlist({'idx' : 3, 'items' : 0}).items)
5060 %bwipe!
5061endfunc
5062
5063func Test_getqflist_by_idx()
5064 call Xtest_getqflist_by_idx('c')
5065 call Xtest_getqflist_by_idx('l')
5066endfunc
5067
5068" Test for the 'quickfixtextfunc' setting
5069func Tqfexpr(info)
5070 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005071 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005072 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005073 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005074 endif
5075
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005076 let l = []
5077 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5078 let e = qfl[idx]
5079 let s = ''
5080 if e.bufnr != 0
5081 let bname = bufname(e.bufnr)
5082 let s ..= fnamemodify(bname, ':.')
5083 endif
5084 let s ..= '-'
5085 let s ..= 'L' .. string(e.lnum) .. 'C' .. string(e.col) .. '-'
5086 let s ..= e.text
5087 call add(l, s)
5088 endfor
Bram Moolenaar858ba062020-05-31 23:11:59 +02005089
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005090 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005091endfunc
5092
5093func Xtest_qftextfunc(cchar)
5094 call s:setup_commands(a:cchar)
5095
5096 set efm=%f:%l:%c:%m
5097 set quickfixtextfunc=Tqfexpr
Bram Moolenaard43906d2020-07-20 21:31:32 +02005098 call assert_equal('Tqfexpr', &quickfixtextfunc)
5099 call assert_equal('',
5100 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005101 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5102 Xwindow
5103 call assert_equal('F1-L10C2-green', getline(1))
5104 call assert_equal('F1-L20C4-blue', getline(2))
5105 Xclose
5106 set quickfixtextfunc&vim
5107 Xwindow
5108 call assert_equal('F1|10 col 2| green', getline(1))
5109 call assert_equal('F1|20 col 4| blue', getline(2))
5110 Xclose
5111 set efm&
5112 set quickfixtextfunc&
5113
5114 " Test for per list 'quickfixtextfunc' setting
5115 func PerQfText(info)
5116 if a:info.quickfix
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005117 let qfl = getqflist({'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005118 else
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005119 let qfl = getloclist(a:info.winid, {'id' : a:info.id, 'items' : 1}).items
Bram Moolenaar858ba062020-05-31 23:11:59 +02005120 endif
5121 if empty(qfl)
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005122 return []
Bram Moolenaar858ba062020-05-31 23:11:59 +02005123 endif
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005124 let l = []
5125 for idx in range(a:info.start_idx - 1, a:info.end_idx - 1)
5126 call add(l, 'Line ' .. qfl[idx].lnum .. ', Col ' .. qfl[idx].col)
5127 endfor
5128 return l
Bram Moolenaar858ba062020-05-31 23:11:59 +02005129 endfunc
5130 set quickfixtextfunc=Tqfexpr
5131 call g:Xsetlist([], ' ', {'quickfixtextfunc' : "PerQfText"})
5132 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5133 Xwindow
5134 call assert_equal('Line 10, Col 2', getline(1))
5135 call assert_equal('Line 20, Col 4', getline(2))
5136 Xclose
Bram Moolenaard43906d2020-07-20 21:31:32 +02005137 call assert_equal(function('PerQfText'),
5138 \ g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar7ba5a7e2020-06-08 19:20:27 +02005139 " Add entries to the list when the quickfix buffer is hidden
5140 Xaddexpr ['F1:30:6:red']
5141 Xwindow
5142 call assert_equal('Line 30, Col 6', getline(3))
5143 Xclose
Bram Moolenaar858ba062020-05-31 23:11:59 +02005144 call g:Xsetlist([], 'r', {'quickfixtextfunc' : ''})
Bram Moolenaard43906d2020-07-20 21:31:32 +02005145 call assert_equal('', g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc)
Bram Moolenaar858ba062020-05-31 23:11:59 +02005146 set quickfixtextfunc&
5147 delfunc PerQfText
5148
5149 " Non-existing function
5150 set quickfixtextfunc=Tabc
5151 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5152 call assert_fails("Xwindow", 'E117:')
5153 Xclose
5154 set quickfixtextfunc&
5155
5156 " set option to a non-function
5157 set quickfixtextfunc=[10,\ 20]
5158 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E117:')
5159 call assert_fails("Xwindow", 'E117:')
5160 Xclose
5161 set quickfixtextfunc&
5162
5163 " set option to a function with different set of arguments
5164 func Xqftext(a, b, c)
5165 return a:a .. a:b .. a:c
5166 endfunc
5167 set quickfixtextfunc=Xqftext
5168 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue']", 'E119:')
5169 call assert_fails("Xwindow", 'E119:')
5170 Xclose
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005171
5172 " set option to a function that returns a list with non-strings
5173 func Xqftext2(d)
5174 return ['one', [], 'two']
5175 endfunc
5176 set quickfixtextfunc=Xqftext2
5177 call assert_fails("Xexpr ['F1:10:2:green', 'F1:20:4:blue', 'F1:30:6:red']",
5178 \ 'E730:')
5179 call assert_fails('Xwindow', 'E730:')
Bram Moolenaard43906d2020-07-20 21:31:32 +02005180 call assert_equal(['one', 'F1|20 col 4| blue', 'F1|30 col 6| red'],
5181 \ getline(1, '$'))
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005182 Xclose
5183
Bram Moolenaar858ba062020-05-31 23:11:59 +02005184 set quickfixtextfunc&
5185 delfunc Xqftext
Bram Moolenaar00e260b2020-06-11 19:35:52 +02005186 delfunc Xqftext2
Bram Moolenaard43906d2020-07-20 21:31:32 +02005187
5188 " set the global option to a lambda function
5189 set quickfixtextfunc={d\ ->\ map(g:Xgetlist({'id'\ :\ d.id,\ 'items'\ :\ 1}).items[d.start_idx-1:d.end_idx-1],\ 'v:val.text')}
5190 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5191 Xwindow
5192 call assert_equal(['green', 'blue'], getline(1, '$'))
5193 Xclose
5194 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)
5195 set quickfixtextfunc&
5196
5197 " use a lambda function that returns an empty list
5198 set quickfixtextfunc={d\ ->\ []}
5199 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5200 Xwindow
5201 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5202 \ getline(1, '$'))
5203 Xclose
5204 set quickfixtextfunc&
5205
5206 " use a lambda function that returns a list with empty strings
5207 set quickfixtextfunc={d\ ->\ ['',\ '']}
5208 Xexpr ['F1:10:2:green', 'F1:20:4:blue']
5209 Xwindow
5210 call assert_equal(['F1|10 col 2| green', 'F1|20 col 4| blue'],
5211 \ getline(1, '$'))
5212 Xclose
5213 set quickfixtextfunc&
5214
5215 " set the per-quickfix list text function to a lambda function
5216 call g:Xsetlist([], ' ',
5217 \ {'quickfixtextfunc' :
5218 \ {d -> map(g:Xgetlist({'id' : d.id, 'items' : 1}).items[d.start_idx-1:d.end_idx-1],
5219 \ "'Line ' .. v:val.lnum .. ', Col ' .. v:val.col")}})
5220 Xaddexpr ['F1:10:2:green', 'F1:20:4:blue']
5221 Xwindow
5222 call assert_equal('Line 10, Col 2', getline(1))
5223 call assert_equal('Line 20, Col 4', getline(2))
5224 Xclose
5225 call assert_match("function('<lambda>\\d\\+')", string(g:Xgetlist({'quickfixtextfunc' : 1}).quickfixtextfunc))
5226 call g:Xsetlist([], 'f')
Bram Moolenaar858ba062020-05-31 23:11:59 +02005227endfunc
5228
5229func Test_qftextfunc()
5230 call Xtest_qftextfunc('c')
5231 call Xtest_qftextfunc('l')
5232endfunc
5233
Bram Moolenaarec98e932020-06-08 19:35:59 +02005234" Running :lhelpgrep command more than once in a help window, doesn't jump to
5235" the help topic
5236func Test_lhelpgrep_from_help_window()
5237 call mkdir('Xtestdir/doc', 'p')
5238 call writefile(['window'], 'Xtestdir/doc/a.txt')
5239 call writefile(['buffer'], 'Xtestdir/doc/b.txt')
5240 let save_rtp = &rtp
5241 let &rtp = 'Xtestdir'
5242 lhelpgrep window
5243 lhelpgrep buffer
5244 call assert_equal('b.txt', fnamemodify(@%, ":p:t"))
5245 lhelpgrep window
5246 call assert_equal('a.txt', fnamemodify(@%, ":p:t"))
5247 let &rtp = save_rtp
5248 call delete('Xtestdir', 'rf')
5249 new | only!
5250endfunc
5251
Bram Moolenaarf7c4d832020-08-11 20:42:19 +02005252" Test for the crash fixed by 7.3.715
5253func Test_setloclist_crash()
5254 %bw!
5255 let g:BufNum = bufnr()
5256 augroup QF_Test
5257 au!
5258 au BufUnload * call setloclist(0, [{'bufnr':g:BufNum, 'lnum':1, 'col':1, 'text': 'tango down'}])
5259 augroup END
5260
5261 try
5262 lvimgrep /.*/ *.mak
5263 catch /E926:/
5264 endtry
5265 call assert_equal('tango down', getloclist(0, {'items' : 0}).items[0].text)
5266 call assert_equal(1, getloclist(0, {'size' : 0}).size)
5267
5268 augroup QF_Test
5269 au!
5270 augroup END
5271 unlet g:BufNum
5272 %bw!
5273endfunc
5274
Bram Moolenaar2ce77902020-11-14 13:15:24 +01005275" Test for adding an invalid entry with the quickfix window open and making
5276" sure that the window contents are not changed
5277func Test_add_invalid_entry_with_qf_window()
5278 call setqflist([], 'f')
5279 cexpr "Xfile1:10:aa"
5280 copen
5281 call setqflist(['bb'], 'a')
5282 call assert_equal(1, line('$'))
5283 call assert_equal(['Xfile1|10| aa'], getline(1, '$'))
5284 call assert_equal([{'lnum': 10, 'bufnr': bufnr('Xfile1'), 'col': 0, 'pattern': '', 'valid': 1, 'vcol': 0, 'nr': -1, 'type': '', 'module': '', 'text': 'aa'}], getqflist())
5285 cclose
5286endfunc
5287
Bram Moolenaar9e40c4b2020-11-23 20:15:08 +01005288" Test for very weird problem: autocommand causes a failure, resulting opening
5289" the quickfix window to fail. This still splits the window, but otherwise
5290" should not mess up buffers.
5291func Test_quickfix_window_fails_to_open()
5292 CheckScreendump
5293
5294 let lines =<< trim END
5295 anything
5296 try
5297 anything
5298 endtry
5299 END
5300 call writefile(lines, 'XquickfixFails')
5301
5302 let lines =<< trim END
5303 split XquickfixFails
5304 silent vimgrep anything %
5305 normal o
5306 au BufLeave * ++once source XquickfixFails
5307 " This will trigger the autocommand, which causes an error, what follows
5308 " is aborted but the window was already split.
5309 silent! cwindow
5310 END
5311 call writefile(lines, 'XtestWinFails')
5312 let buf = RunVimInTerminal('-S XtestWinFails', #{rows: 13})
5313 call VerifyScreenDump(buf, 'Test_quickfix_window_fails', {})
5314
5315 " clean up
5316 call term_sendkeys(buf, ":bwipe!\<CR>")
5317 call term_wait(buf)
5318 call StopVimInTerminal(buf)
5319 call delete('XtestWinFails')
5320 call delete('XquickfixFails')
5321endfunc
5322
Bram Moolenaar2d870f82020-12-05 13:41:01 +01005323" Test for updating the quickfix buffer whenever the associated quickfix list
Bram Moolenaar287153c2020-11-29 14:20:27 +01005324" is changed.
5325func Xqfbuf_update(cchar)
5326 call s:setup_commands(a:cchar)
5327
5328 Xexpr "F1:1:line1"
5329 Xopen
5330 call assert_equal(['F1|1| line1'], getline(1, '$'))
5331 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5332
5333 " Test setqflist() using the 'lines' key in 'what'
5334 " add a new entry
5335 call g:Xsetlist([], 'a', {'lines' : ['F2:2: line2']})
5336 call assert_equal(['F1|1| line1', 'F2|2| line2'], getline(1, '$'))
5337 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5338 " replace all the entries with a single entry
5339 call g:Xsetlist([], 'r', {'lines' : ['F3:3: line3']})
5340 call assert_equal(['F3|3| line3'], getline(1, '$'))
5341 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5342 " remove all the entries
5343 call g:Xsetlist([], 'r', {'lines' : []})
5344 call assert_equal([''], getline(1, '$'))
5345 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5346 " add a new list
5347 call g:Xsetlist([], ' ', {'lines' : ['F4:4: line4']})
5348 call assert_equal(['F4|4| line4'], getline(1, '$'))
5349 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5350
5351 " Test setqflist() using the 'items' key in 'what'
5352 " add a new entry
5353 call g:Xsetlist([], 'a', {'items' : [{'filename' : 'F5', 'lnum' : 5, 'text' : 'line5'}]})
5354 call assert_equal(['F4|4| line4', 'F5|5| line5'], getline(1, '$'))
5355 call assert_equal(2, g:Xgetlist({'changedtick' : 0}).changedtick)
5356 " replace all the entries with a single entry
5357 call g:Xsetlist([], 'r', {'items' : [{'filename' : 'F6', 'lnum' : 6, 'text' : 'line6'}]})
5358 call assert_equal(['F6|6| line6'], getline(1, '$'))
5359 call assert_equal(3, g:Xgetlist({'changedtick' : 0}).changedtick)
5360 " remove all the entries
5361 call g:Xsetlist([], 'r', {'items' : []})
5362 call assert_equal([''], getline(1, '$'))
5363 call assert_equal(4, g:Xgetlist({'changedtick' : 0}).changedtick)
5364 " add a new list
5365 call g:Xsetlist([], ' ', {'items' : [{'filename' : 'F7', 'lnum' : 7, 'text' : 'line7'}]})
5366 call assert_equal(['F7|7| line7'], getline(1, '$'))
5367 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5368
5369 call g:Xsetlist([], ' ', {})
5370 call assert_equal([''], getline(1, '$'))
5371 call assert_equal(1, g:Xgetlist({'changedtick' : 0}).changedtick)
5372
5373 Xclose
5374endfunc
5375
5376func Test_qfbuf_update()
5377 call Xqfbuf_update('c')
5378 call Xqfbuf_update('l')
5379endfunc
5380
Bram Moolenaar8c801b32021-03-05 20:58:22 +01005381func Test_vimgrep_noswapfile()
5382 set noswapfile
5383 call writefile(['one', 'two', 'three'], 'Xgreppie')
5384 vimgrep two Xgreppie
5385 call assert_equal('two', getline('.'))
5386
5387 call delete('Xgreppie')
5388 set swapfile
5389endfunc
5390
Yegappan Lakshmananbb01a1e2021-04-26 21:17:52 +02005391" Test for the :vimgrep 'f' flag (fuzzy match)
5392func Xvimgrep_fuzzy_match(cchar)
5393 call s:setup_commands(a:cchar)
5394
5395 Xvimgrep /three one/f Xfile*
5396 let l = g:Xgetlist()
5397 call assert_equal(2, len(l))
5398 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5399 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5400 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5401 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5402
5403 Xvimgrep /the/f Xfile*
5404 let l = g:Xgetlist()
5405 call assert_equal(3, len(l))
5406 call assert_equal(['Xfile1', 1, 9, 'one two three'],
5407 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5408 call assert_equal(['Xfile2', 2, 1, 'three one two'],
5409 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5410 call assert_equal(['Xfile2', 4, 4, 'aaathreeaaa'],
5411 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5412
5413 Xvimgrep /aaa/fg Xfile*
5414 let l = g:Xgetlist()
5415 call assert_equal(4, len(l))
5416 call assert_equal(['Xfile1', 2, 1, 'aaaaaa'],
5417 \ [bufname(l[0].bufnr), l[0].lnum, l[0].col, l[0].text])
5418 call assert_equal(['Xfile1', 2, 4, 'aaaaaa'],
5419 \ [bufname(l[1].bufnr), l[1].lnum, l[1].col, l[1].text])
5420 call assert_equal(['Xfile2', 4, 1, 'aaathreeaaa'],
5421 \ [bufname(l[2].bufnr), l[2].lnum, l[2].col, l[2].text])
5422 call assert_equal(['Xfile2', 4, 9, 'aaathreeaaa'],
5423 \ [bufname(l[3].bufnr), l[3].lnum, l[3].col, l[3].text])
5424
5425 call assert_fails('Xvimgrep /xyz/fg Xfile*', 'E480:')
5426endfunc
5427
5428func Test_vimgrep_fuzzy_match()
5429 call writefile(['one two three', 'aaaaaa'], 'Xfile1')
5430 call writefile(['one', 'three one two', 'two', 'aaathreeaaa'], 'Xfile2')
5431 call Xvimgrep_fuzzy_match('c')
5432 call Xvimgrep_fuzzy_match('l')
5433 call delete('Xfile1')
5434 call delete('Xfile2')
5435endfunc
5436
Bram Moolenaar6a0cc912019-10-26 16:48:44 +02005437" vim: shiftwidth=2 sts=2 expandtab