blob: 6f27fe512c584a0340828f8a258e4b6b7b2faea4 [file] [log] [blame]
Bram Moolenaar14735512016-03-26 21:00:08 +01001" Tests for autocommands
2
Bram Moolenaar8c64a362018-03-23 22:39:31 +01003source shared.vim
4
Bram Moolenaar1e115362019-01-09 23:01:02 +01005func s:cleanup_buffers() abort
Bram Moolenaarb3435b02016-09-29 20:54:59 +02006 for bnr in range(1, bufnr('$'))
7 if bufloaded(bnr) && bufnr('%') != bnr
8 execute 'bd! ' . bnr
9 endif
10 endfor
Bram Moolenaar04f62f82017-07-19 18:18:39 +020011endfunc
Bram Moolenaarb3435b02016-09-29 20:54:59 +020012
Bram Moolenaar14735512016-03-26 21:00:08 +010013func Test_vim_did_enter()
14 call assert_false(v:vim_did_enter)
15
16 " This script will never reach the main loop, can't check if v:vim_did_enter
17 " becomes one.
18endfunc
Bram Moolenaar40b1b542016-04-20 20:18:23 +020019
Bram Moolenaarc67e8922016-05-24 16:07:40 +020020if has('timers')
21 func ExitInsertMode(id)
22 call feedkeys("\<Esc>")
23 endfunc
24
25 func Test_cursorhold_insert()
Bram Moolenaarf18c4db2016-09-08 22:10:06 +020026 " Need to move the cursor.
27 call feedkeys("ggG", "xt")
28
Bram Moolenaarc67e8922016-05-24 16:07:40 +020029 let g:triggered = 0
30 au CursorHoldI * let g:triggered += 1
31 set updatetime=20
32 call timer_start(100, 'ExitInsertMode')
33 call feedkeys('a', 'x!')
34 call assert_equal(1, g:triggered)
Bram Moolenaare99e8442016-07-26 20:43:40 +020035 au! CursorHoldI
Bram Moolenaaraeac9002016-09-06 22:15:08 +020036 set updatetime&
Bram Moolenaarc67e8922016-05-24 16:07:40 +020037 endfunc
38
39 func Test_cursorhold_insert_ctrl_x()
40 let g:triggered = 0
41 au CursorHoldI * let g:triggered += 1
42 set updatetime=20
43 call timer_start(100, 'ExitInsertMode')
44 " CursorHoldI does not trigger after CTRL-X
45 call feedkeys("a\<C-X>", 'x!')
46 call assert_equal(0, g:triggered)
Bram Moolenaare99e8442016-07-26 20:43:40 +020047 au! CursorHoldI
Bram Moolenaaraeac9002016-09-06 22:15:08 +020048 set updatetime&
Bram Moolenaarc67e8922016-05-24 16:07:40 +020049 endfunc
Bram Moolenaar40b1b542016-04-20 20:18:23 +020050endif
51
Bram Moolenaar04f62f82017-07-19 18:18:39 +020052func Test_bufunload()
Bram Moolenaarc67e8922016-05-24 16:07:40 +020053 augroup test_bufunload_group
54 autocmd!
55 autocmd BufUnload * call add(s:li, "bufunload")
56 autocmd BufDelete * call add(s:li, "bufdelete")
57 autocmd BufWipeout * call add(s:li, "bufwipeout")
58 augroup END
Bram Moolenaar40b1b542016-04-20 20:18:23 +020059
Bram Moolenaarc67e8922016-05-24 16:07:40 +020060 let s:li=[]
61 new
62 setlocal bufhidden=
63 bunload
64 call assert_equal(["bufunload", "bufdelete"], s:li)
Bram Moolenaar40b1b542016-04-20 20:18:23 +020065
Bram Moolenaarc67e8922016-05-24 16:07:40 +020066 let s:li=[]
67 new
68 setlocal bufhidden=delete
69 bunload
70 call assert_equal(["bufunload", "bufdelete"], s:li)
71
72 let s:li=[]
73 new
74 setlocal bufhidden=unload
75 bwipeout
76 call assert_equal(["bufunload", "bufdelete", "bufwipeout"], s:li)
77
Bram Moolenaare99e8442016-07-26 20:43:40 +020078 au! test_bufunload_group
Bram Moolenaarc67e8922016-05-24 16:07:40 +020079 augroup! test_bufunload_group
Bram Moolenaar40b1b542016-04-20 20:18:23 +020080endfunc
Bram Moolenaar30445cb2016-07-09 15:21:02 +020081
82" SEGV occurs in older versions. (At least 7.4.2005 or older)
Bram Moolenaar04f62f82017-07-19 18:18:39 +020083func Test_autocmd_bufunload_with_tabnext()
Bram Moolenaar30445cb2016-07-09 15:21:02 +020084 tabedit
85 tabfirst
86
87 augroup test_autocmd_bufunload_with_tabnext_group
88 autocmd!
89 autocmd BufUnload <buffer> tabnext
90 augroup END
91
92 quit
93 call assert_equal(2, tabpagenr('$'))
94
Bram Moolenaare0ab94e2016-09-04 19:50:54 +020095 autocmd! test_autocmd_bufunload_with_tabnext_group
Bram Moolenaar30445cb2016-07-09 15:21:02 +020096 augroup! test_autocmd_bufunload_with_tabnext_group
97 tablast
98 quit
99endfunc
Bram Moolenaarc917da42016-07-19 22:31:36 +0200100
Bram Moolenaar04f62f82017-07-19 18:18:39 +0200101func Test_autocmd_bufwinleave_with_tabfirst()
Bram Moolenaarf9e687e2016-09-04 21:33:09 +0200102 tabedit
103 augroup sample
104 autocmd!
105 autocmd BufWinLeave <buffer> tabfirst
106 augroup END
107 call setline(1, ['a', 'b', 'c'])
108 edit! a.txt
Bram Moolenaarf18c4db2016-09-08 22:10:06 +0200109 tabclose
Bram Moolenaarf9e687e2016-09-04 21:33:09 +0200110endfunc
111
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200112" SEGV occurs in older versions. (At least 7.4.2321 or older)
Bram Moolenaar04f62f82017-07-19 18:18:39 +0200113func Test_autocmd_bufunload_avoiding_SEGV_01()
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200114 split aa.txt
115 let lastbuf = bufnr('$')
116
117 augroup test_autocmd_bufunload
118 autocmd!
119 exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!'
120 augroup END
121
Bram Moolenaara997b452018-04-17 23:24:06 +0200122 " Todo: check for E937 generated first
123 " call assert_fails('edit bb.txt', 'E937:')
124 call assert_fails('edit bb.txt', 'E517:')
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200125
126 autocmd! test_autocmd_bufunload
127 augroup! test_autocmd_bufunload
128 bwipe! aa.txt
129 bwipe! bb.txt
130endfunc
131
132" SEGV occurs in older versions. (At least 7.4.2321 or older)
Bram Moolenaar04f62f82017-07-19 18:18:39 +0200133func Test_autocmd_bufunload_avoiding_SEGV_02()
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200134 setlocal buftype=nowrite
135 let lastbuf = bufnr('$')
136
137 augroup test_autocmd_bufunload
138 autocmd!
139 exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!'
140 augroup END
141
142 normal! i1
143 call assert_fails('edit a.txt', 'E517:')
144 call feedkeys("\<CR>")
145
146 autocmd! test_autocmd_bufunload
147 augroup! test_autocmd_bufunload
148 bwipe! a.txt
149endfunc
150
Bram Moolenaarc917da42016-07-19 22:31:36 +0200151func Test_win_tab_autocmd()
152 let g:record = []
153
154 augroup testing
155 au WinNew * call add(g:record, 'WinNew')
156 au WinEnter * call add(g:record, 'WinEnter')
157 au WinLeave * call add(g:record, 'WinLeave')
158 au TabNew * call add(g:record, 'TabNew')
Bram Moolenaar12c11d52016-07-19 23:13:03 +0200159 au TabClosed * call add(g:record, 'TabClosed')
Bram Moolenaarc917da42016-07-19 22:31:36 +0200160 au TabEnter * call add(g:record, 'TabEnter')
161 au TabLeave * call add(g:record, 'TabLeave')
162 augroup END
163
164 split
165 tabnew
166 close
167 close
168
169 call assert_equal([
170 \ 'WinLeave', 'WinNew', 'WinEnter',
171 \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
Bram Moolenaar12c11d52016-07-19 23:13:03 +0200172 \ 'WinLeave', 'TabLeave', 'TabClosed', 'WinEnter', 'TabEnter',
Bram Moolenaarc917da42016-07-19 22:31:36 +0200173 \ 'WinLeave', 'WinEnter'
174 \ ], g:record)
175
Bram Moolenaar12c11d52016-07-19 23:13:03 +0200176 let g:record = []
177 tabnew somefile
178 tabnext
179 bwipe somefile
180
181 call assert_equal([
182 \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
183 \ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter',
184 \ 'TabClosed'
185 \ ], g:record)
186
Bram Moolenaarc917da42016-07-19 22:31:36 +0200187 augroup testing
188 au!
189 augroup END
190 unlet g:record
191endfunc
Bram Moolenaare99e8442016-07-26 20:43:40 +0200192
193func s:AddAnAutocmd()
194 augroup vimBarTest
195 au BufReadCmd * echo 'hello'
196 augroup END
197 call assert_equal(3, len(split(execute('au vimBarTest'), "\n")))
198endfunc
199
200func Test_early_bar()
201 " test that a bar is recognized before the {event}
202 call s:AddAnAutocmd()
203 augroup vimBarTest | au! | augroup END
204 call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
205
206 call s:AddAnAutocmd()
207 augroup vimBarTest| au!| augroup END
208 call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
209
210 " test that a bar is recognized after the {event}
211 call s:AddAnAutocmd()
212 augroup vimBarTest| au!BufReadCmd| augroup END
213 call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
214
215 " test that a bar is recognized after the {group}
216 call s:AddAnAutocmd()
217 au! vimBarTest|echo 'hello'
218 call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
219endfunc
Bram Moolenaarf2c4c392016-07-29 20:50:24 +0200220
Bram Moolenaar5c809082016-09-01 16:21:48 +0200221func RemoveGroup()
222 autocmd! StartOK
223 augroup! StartOK
224endfunc
225
Bram Moolenaarf2c4c392016-07-29 20:50:24 +0200226func Test_augroup_warning()
227 augroup TheWarning
228 au VimEnter * echo 'entering'
229 augroup END
230 call assert_true(match(execute('au VimEnter'), "TheWarning.*VimEnter") >= 0)
231 redir => res
232 augroup! TheWarning
233 redir END
234 call assert_true(match(res, "W19:") >= 0)
235 call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0)
236
237 " check "Another" does not take the pace of the deleted entry
238 augroup Another
239 augroup END
240 call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0)
Bram Moolenaaraeac9002016-09-06 22:15:08 +0200241 augroup! Another
Bram Moolenaar5c809082016-09-01 16:21:48 +0200242
243 " no warning for postpone aucmd delete
244 augroup StartOK
245 au VimEnter * call RemoveGroup()
246 augroup END
247 call assert_true(match(execute('au VimEnter'), "StartOK.*VimEnter") >= 0)
248 redir => res
249 doautocmd VimEnter
250 redir END
251 call assert_true(match(res, "W19:") < 0)
Bram Moolenaarde653f02016-09-03 16:59:06 +0200252 au! VimEnter
Bram Moolenaarf2c4c392016-07-29 20:50:24 +0200253endfunc
Bram Moolenaarb62cc362016-09-03 16:43:53 +0200254
Bram Moolenaar8d84ff12017-10-26 16:42:16 +0200255func Test_BufReadCmdHelp()
256 " This used to cause access to free memory
257 au BufReadCmd * e +h
258 help
259
Bram Moolenaar8d84ff12017-10-26 16:42:16 +0200260 au! BufReadCmd
261endfunc
262
263func Test_BufReadCmdHelpJump()
264 " This used to cause access to free memory
265 au BufReadCmd * e +h{
Bram Moolenaarcf1ba352017-10-27 00:55:04 +0200266 " } to fix highlighting
267 call assert_fails('help', 'E434:')
Bram Moolenaar8d84ff12017-10-26 16:42:16 +0200268
Bram Moolenaar8d84ff12017-10-26 16:42:16 +0200269 au! BufReadCmd
270endfunc
271
Bram Moolenaarb62cc362016-09-03 16:43:53 +0200272func Test_augroup_deleted()
Bram Moolenaarde653f02016-09-03 16:59:06 +0200273 " This caused a crash before E936 was introduced
Bram Moolenaarb62cc362016-09-03 16:43:53 +0200274 augroup x
Bram Moolenaarde653f02016-09-03 16:59:06 +0200275 call assert_fails('augroup! x', 'E936:')
276 au VimEnter * echo
277 augroup end
Bram Moolenaarb62cc362016-09-03 16:43:53 +0200278 augroup! x
Bram Moolenaarde653f02016-09-03 16:59:06 +0200279 call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0)
280 au! VimEnter
Bram Moolenaarb62cc362016-09-03 16:43:53 +0200281endfunc
282
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200283" Tests for autocommands on :close command.
284" This used to be in test13.
285func Test_three_windows()
Bram Moolenaarb3435b02016-09-29 20:54:59 +0200286 " Clean up buffers, because in some cases this function fails.
287 call s:cleanup_buffers()
288
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200289 " Write three files and open them, each in a window.
290 " Then go to next window, with autocommand that deletes the previous one.
291 " Do this twice, writing the file.
292 e! Xtestje1
293 call setline(1, 'testje1')
294 w
295 sp Xtestje2
296 call setline(1, 'testje2')
297 w
298 sp Xtestje3
299 call setline(1, 'testje3')
300 w
301 wincmd w
302 au WinLeave Xtestje2 bwipe
303 wincmd w
304 call assert_equal('Xtestje1', expand('%'))
305
306 au WinLeave Xtestje1 bwipe Xtestje3
307 close
308 call assert_equal('Xtestje1', expand('%'))
309
310 " Test deleting the buffer on a Unload event. If this goes wrong there
311 " will be the ATTENTION prompt.
312 e Xtestje1
313 au!
314 au! BufUnload Xtestje1 bwipe
315 call assert_fails('e Xtestje3', 'E937:')
316 call assert_equal('Xtestje3', expand('%'))
317
318 e Xtestje2
319 sp Xtestje1
320 call assert_fails('e', 'E937:')
Bram Moolenaara997b452018-04-17 23:24:06 +0200321 call assert_equal('Xtestje1', expand('%'))
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200322
323 " Test changing buffers in a BufWipeout autocommand. If this goes wrong
324 " there are ml_line errors and/or a Crash.
325 au!
326 only
327 e Xanother
328 e Xtestje1
329 bwipe Xtestje2
330 bwipe Xtestje3
331 au BufWipeout Xtestje1 buf Xtestje1
332 bwipe
333 call assert_equal('Xanother', expand('%'))
334
335 only
336 help
337 wincmd w
338 1quit
339 call assert_equal('Xanother', expand('%'))
340
341 au!
Bram Moolenaar4520d442017-03-19 16:09:46 +0100342 enew
Bram Moolenaare0ab94e2016-09-04 19:50:54 +0200343 call delete('Xtestje1')
344 call delete('Xtestje2')
345 call delete('Xtestje3')
346endfunc
Bram Moolenaare13b9af2017-01-13 22:01:02 +0100347
348func Test_BufEnter()
349 au! BufEnter
350 au Bufenter * let val = val . '+'
351 let g:val = ''
352 split NewFile
353 call assert_equal('+', g:val)
354 bwipe!
355 call assert_equal('++', g:val)
356
357 " Also get BufEnter when editing a directory
358 call mkdir('Xdir')
359 split Xdir
360 call assert_equal('+++', g:val)
Bram Moolenaare94260f2017-03-21 15:50:12 +0100361
362 " On MS-Windows we can't edit the directory, make sure we wipe the right
363 " buffer.
364 bwipe! Xdir
Bram Moolenaare13b9af2017-01-13 22:01:02 +0100365
366 call delete('Xdir', 'd')
367 au! BufEnter
368endfunc
Bram Moolenaar8c752bd2017-03-19 17:09:56 +0100369
370" Closing a window might cause an endless loop
371" E814 for older Vims
Bram Moolenaar04f62f82017-07-19 18:18:39 +0200372func Test_autocmd_bufwipe_in_SessLoadPost()
Bram Moolenaar1d68d9b2017-10-13 22:33:32 +0200373 edit Xtest
Bram Moolenaar8c752bd2017-03-19 17:09:56 +0100374 tabnew
Bram Moolenaar1d68d9b2017-10-13 22:33:32 +0200375 file Xsomething
Bram Moolenaar8c752bd2017-03-19 17:09:56 +0100376 set noswapfile
Bram Moolenaar8c752bd2017-03-19 17:09:56 +0100377 mksession!
378
Bram Moolenaare94260f2017-03-21 15:50:12 +0100379 let content = ['set nocp noswapfile',
Bram Moolenaar8c752bd2017-03-19 17:09:56 +0100380 \ 'let v:swapchoice="e"',
381 \ 'augroup test_autocmd_sessionload',
382 \ 'autocmd!',
Bram Moolenaar1d68d9b2017-10-13 22:33:32 +0200383 \ 'autocmd SessionLoadPost * exe bufnr("Xsomething") . "bw!"',
Bram Moolenaare94260f2017-03-21 15:50:12 +0100384 \ 'augroup END',
385 \ '',
386 \ 'func WriteErrors()',
387 \ ' call writefile([execute("messages")], "Xerrors")',
388 \ 'endfunc',
389 \ 'au VimLeave * call WriteErrors()',
Bram Moolenaar8c752bd2017-03-19 17:09:56 +0100390 \ ]
391 call writefile(content, 'Xvimrc')
Bram Moolenaare94260f2017-03-21 15:50:12 +0100392 call system(v:progpath. ' -u Xvimrc --not-a-term --noplugins -S Session.vim -c cq')
393 let errors = join(readfile('Xerrors'))
394 call assert_match('E814', errors)
Bram Moolenaar8c752bd2017-03-19 17:09:56 +0100395
Bram Moolenaar8c752bd2017-03-19 17:09:56 +0100396 set swapfile
Bram Moolenaare94260f2017-03-21 15:50:12 +0100397 for file in ['Session.vim', 'Xvimrc', 'Xerrors']
Bram Moolenaar8c752bd2017-03-19 17:09:56 +0100398 call delete(file)
399 endfor
400endfunc
401
402" SEGV occurs in older versions.
Bram Moolenaar04f62f82017-07-19 18:18:39 +0200403func Test_autocmd_bufwipe_in_SessLoadPost2()
Bram Moolenaar8c752bd2017-03-19 17:09:56 +0100404 tabnew
405 set noswapfile
Bram Moolenaar8c752bd2017-03-19 17:09:56 +0100406 mksession!
407
408 let content = ['set nocp noswapfile',
409 \ 'function! DeleteInactiveBufs()',
410 \ ' tabfirst',
411 \ ' let tabblist = []',
412 \ ' for i in range(1, tabpagenr(''$''))',
413 \ ' call extend(tabblist, tabpagebuflist(i))',
414 \ ' endfor',
415 \ ' for b in range(1, bufnr(''$''))',
416 \ ' if bufexists(b) && buflisted(b) && (index(tabblist, b) == -1 || bufname(b) =~# ''^$'')',
417 \ ' exec ''bwipeout '' . b',
418 \ ' endif',
419 \ ' endfor',
Bram Moolenaare94260f2017-03-21 15:50:12 +0100420 \ ' echomsg "SessionLoadPost DONE"',
Bram Moolenaar8c752bd2017-03-19 17:09:56 +0100421 \ 'endfunction',
Bram Moolenaare94260f2017-03-21 15:50:12 +0100422 \ 'au SessionLoadPost * call DeleteInactiveBufs()',
423 \ '',
424 \ 'func WriteErrors()',
425 \ ' call writefile([execute("messages")], "Xerrors")',
426 \ 'endfunc',
427 \ 'au VimLeave * call WriteErrors()',
428 \ ]
Bram Moolenaar8c752bd2017-03-19 17:09:56 +0100429 call writefile(content, 'Xvimrc')
Bram Moolenaare94260f2017-03-21 15:50:12 +0100430 call system(v:progpath. ' -u Xvimrc --not-a-term --noplugins -S Session.vim -c cq')
431 let errors = join(readfile('Xerrors'))
432 " This probably only ever matches on unix.
433 call assert_notmatch('Caught deadly signal SEGV', errors)
434 call assert_match('SessionLoadPost DONE', errors)
Bram Moolenaar8c752bd2017-03-19 17:09:56 +0100435
Bram Moolenaar8c752bd2017-03-19 17:09:56 +0100436 set swapfile
Bram Moolenaare94260f2017-03-21 15:50:12 +0100437 for file in ['Session.vim', 'Xvimrc', 'Xerrors']
Bram Moolenaar8c752bd2017-03-19 17:09:56 +0100438 call delete(file)
439 endfor
440endfunc
Bram Moolenaarfaf29d72017-07-09 11:07:16 +0200441
442func Test_empty_doau()
443 doau \|
444endfunc
Bram Moolenaar04f62f82017-07-19 18:18:39 +0200445
446func s:AutoCommandOptionSet(match)
447 let item = remove(g:options, 0)
448 let expected = printf("Option: <%s>, Oldval: <%s>, NewVal: <%s>, Scope: <%s>\n", item[0], item[1], item[2], item[3])
449 let actual = printf("Option: <%s>, Oldval: <%s>, NewVal: <%s>, Scope: <%s>\n", a:match, v:option_old, v:option_new, v:option_type)
450 let g:opt = [expected, actual]
451 "call assert_equal(expected, actual)
452endfunc
453
454func Test_OptionSet()
455 if !has("eval") || !has("autocmd") || !exists("+autochdir")
456 return
457 endif
458
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +0200459 badd test_autocmd.vim
460
Bram Moolenaar04f62f82017-07-19 18:18:39 +0200461 call test_override('starting', 1)
462 set nocp
463 au OptionSet * :call s:AutoCommandOptionSet(expand("<amatch>"))
464
465 " 1: Setting number option"
466 let g:options=[['number', 0, 1, 'global']]
467 set nu
468 call assert_equal([], g:options)
469 call assert_equal(g:opt[0], g:opt[1])
470
471 " 2: Setting local number option"
472 let g:options=[['number', 1, 0, 'local']]
473 setlocal nonu
474 call assert_equal([], g:options)
475 call assert_equal(g:opt[0], g:opt[1])
476
477 " 3: Setting global number option"
478 let g:options=[['number', 1, 0, 'global']]
479 setglobal nonu
480 call assert_equal([], g:options)
481 call assert_equal(g:opt[0], g:opt[1])
482
483 " 4: Setting local autoindent option"
484 let g:options=[['autoindent', 0, 1, 'local']]
485 setlocal ai
486 call assert_equal([], g:options)
487 call assert_equal(g:opt[0], g:opt[1])
488
489 " 5: Setting global autoindent option"
490 let g:options=[['autoindent', 0, 1, 'global']]
491 setglobal ai
492 call assert_equal([], g:options)
493 call assert_equal(g:opt[0], g:opt[1])
494
495 " 6: Setting global autoindent option"
496 let g:options=[['autoindent', 1, 0, 'global']]
497 set ai!
498 call assert_equal([], g:options)
499 call assert_equal(g:opt[0], g:opt[1])
500
501 " Should not print anything, use :noa
502 " 7: don't trigger OptionSet"
503 let g:options=[['invalid', 1, 1, 'invalid']]
504 noa set nonu
505 call assert_equal([['invalid', 1, 1, 'invalid']], g:options)
506 call assert_equal(g:opt[0], g:opt[1])
507
508 " 8: Setting several global list and number option"
509 let g:options=[['list', 0, 1, 'global'], ['number', 0, 1, 'global']]
510 set list nu
511 call assert_equal([], g:options)
512 call assert_equal(g:opt[0], g:opt[1])
513
514 " 9: don't trigger OptionSet"
515 let g:options=[['invalid', 1, 1, 'invalid'], ['invalid', 1, 1, 'invalid']]
516 noa set nolist nonu
517 call assert_equal([['invalid', 1, 1, 'invalid'], ['invalid', 1, 1, 'invalid']], g:options)
518 call assert_equal(g:opt[0], g:opt[1])
519
520 " 10: Setting global acd"
521 let g:options=[['autochdir', 0, 1, 'local']]
522 setlocal acd
523 call assert_equal([], g:options)
524 call assert_equal(g:opt[0], g:opt[1])
525
526 " 11: Setting global autoread (also sets local value)"
527 let g:options=[['autoread', 0, 1, 'global']]
528 set ar
529 call assert_equal([], g:options)
530 call assert_equal(g:opt[0], g:opt[1])
531
532 " 12: Setting local autoread"
533 let g:options=[['autoread', 1, 1, 'local']]
534 setlocal ar
535 call assert_equal([], g:options)
536 call assert_equal(g:opt[0], g:opt[1])
537
538 " 13: Setting global autoread"
539 let g:options=[['autoread', 1, 0, 'global']]
540 setglobal invar
541 call assert_equal([], g:options)
542 call assert_equal(g:opt[0], g:opt[1])
543
544 " 14: Setting option backspace through :let"
545 let g:options=[['backspace', '', 'eol,indent,start', 'global']]
546 let &bs="eol,indent,start"
547 call assert_equal([], g:options)
548 call assert_equal(g:opt[0], g:opt[1])
549
550 " 15: Setting option backspace through setbufvar()"
551 let g:options=[['backup', 0, 1, 'local']]
552 " try twice, first time, shouldn't trigger because option name is invalid,
553 " second time, it should trigger
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +0200554 let bnum = bufnr('%')
555 call assert_fails("call setbufvar(bnum, '&l:bk', 1)", "E355")
Bram Moolenaar04f62f82017-07-19 18:18:39 +0200556 " should trigger, use correct option name
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +0200557 call setbufvar(bnum, '&backup', 1)
Bram Moolenaar04f62f82017-07-19 18:18:39 +0200558 call assert_equal([], g:options)
559 call assert_equal(g:opt[0], g:opt[1])
560
561 " 16: Setting number option using setwinvar"
562 let g:options=[['number', 0, 1, 'local']]
563 call setwinvar(0, '&number', 1)
564 call assert_equal([], g:options)
565 call assert_equal(g:opt[0], g:opt[1])
566
567 " 17: Setting key option, shouldn't trigger"
568 let g:options=[['key', 'invalid', 'invalid1', 'invalid']]
569 setlocal key=blah
570 setlocal key=
571 call assert_equal([['key', 'invalid', 'invalid1', 'invalid']], g:options)
572 call assert_equal(g:opt[0], g:opt[1])
573
Bram Moolenaar8efa0262017-08-20 15:47:20 +0200574 " 18: Setting string option"
575 let oldval = &tags
576 let g:options=[['tags', oldval, 'tagpath', 'global']]
577 set tags=tagpath
578 call assert_equal([], g:options)
579 call assert_equal(g:opt[0], g:opt[1])
580
581 " 1l: Resetting string option"
582 let g:options=[['tags', 'tagpath', oldval, 'global']]
583 set tags&
584 call assert_equal([], g:options)
585 call assert_equal(g:opt[0], g:opt[1])
586
Bram Moolenaar04f62f82017-07-19 18:18:39 +0200587 " Cleanup
588 au! OptionSet
589 for opt in ['nu', 'ai', 'acd', 'ar', 'bs', 'backup', 'cul', 'cp']
Bram Moolenaar91d2e782018-08-07 19:05:01 +0200590 exe printf(":set %s&vim", opt)
Bram Moolenaar04f62f82017-07-19 18:18:39 +0200591 endfor
592 call test_override('starting', 0)
593 delfunc! AutoCommandOptionSet
594endfunc
595
596func Test_OptionSet_diffmode()
597 call test_override('starting', 1)
598 " 18: Changing an option when enetering diff mode
599 new
600 au OptionSet diff :let &l:cul=v:option_new
601
602 call setline(1, ['buffer 1', 'line2', 'line3', 'line4'])
603 call assert_equal(0, &l:cul)
604 diffthis
605 call assert_equal(1, &l:cul)
606
607 vnew
608 call setline(1, ['buffer 2', 'line 2', 'line 3', 'line4'])
609 call assert_equal(0, &l:cul)
610 diffthis
611 call assert_equal(1, &l:cul)
612
613 diffoff
614 call assert_equal(0, &l:cul)
615 call assert_equal(1, getwinvar(2, '&l:cul'))
616 bw!
617
618 call assert_equal(1, &l:cul)
619 diffoff!
620 call assert_equal(0, &l:cul)
621 call assert_equal(0, getwinvar(1, '&l:cul'))
622 bw!
623
624 " Cleanup
625 au! OptionSet
626 call test_override('starting', 0)
627endfunc
628
629func Test_OptionSet_diffmode_close()
630 call test_override('starting', 1)
631 " 19: Try to close the current window when entering diff mode
632 " should not segfault
633 new
634 au OptionSet diff close
635
636 call setline(1, ['buffer 1', 'line2', 'line3', 'line4'])
637 call assert_fails(':diffthis', 'E788')
638 call assert_equal(1, &diff)
639 vnew
640 call setline(1, ['buffer 2', 'line 2', 'line 3', 'line4'])
641 call assert_fails(':diffthis', 'E788')
642 call assert_equal(1, &diff)
643 bw!
644 call assert_fails(':diffoff!', 'E788')
645 bw!
646
647 " Cleanup
648 au! OptionSet
649 call test_override('starting', 0)
650 "delfunc! AutoCommandOptionSet
651endfunc
Bram Moolenaar4a137b42017-08-04 22:37:11 +0200652
Bram Moolenaar48f377a2018-12-21 13:03:28 +0100653func Test_OptionSet_modeline()
654 call test_override('starting', 1)
655 au! OptionSet
656 augroup set_tabstop
657 au OptionSet tabstop call timer_start(1, {-> execute("echo 'Handler called'", "")})
658 augroup END
659 call writefile(['vim: set ts=7 sw=5 :', 'something'], 'XoptionsetModeline')
660 set modeline
661 let v:errmsg = ''
662 call assert_fails('split XoptionsetModeline', 'E12:')
663 call assert_equal(7, &ts)
664 call assert_equal('', v:errmsg)
665
666 augroup set_tabstop
667 au!
668 augroup END
669 bwipe!
670 set ts&
671 call delete('XoptionsetModeline')
672 call test_override('starting', 0)
673endfunc
674
Bram Moolenaar4a137b42017-08-04 22:37:11 +0200675" Test for Bufleave autocommand that deletes the buffer we are about to edit.
676func Test_BufleaveWithDelete()
677 new | edit Xfile1
678
679 augroup test_bufleavewithdelete
680 autocmd!
681 autocmd BufLeave Xfile1 bwipe Xfile2
682 augroup END
683
684 call assert_fails('edit Xfile2', 'E143:')
685 call assert_equal('Xfile1', bufname('%'))
686
687 autocmd! test_bufleavewithdelete BufLeave Xfile1
688 augroup! test_bufleavewithdelete
689
690 new
691 bwipe! Xfile1
692endfunc
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +0200693
694" Test for autocommand that changes the buffer list, when doing ":ball".
695func Test_Acmd_BufAll()
696 enew!
697 %bwipe!
698 call writefile(['Test file Xxx1'], 'Xxx1')
699 call writefile(['Test file Xxx2'], 'Xxx2')
700 call writefile(['Test file Xxx3'], 'Xxx3')
701
702 " Add three files to the buffer list
703 split Xxx1
704 close
705 split Xxx2
706 close
707 split Xxx3
708 close
709
710 " Wipe the buffer when the buffer is opened
711 au BufReadPost Xxx2 bwipe
712
713 call append(0, 'Test file Xxx4')
714 ball
715
716 call assert_equal(2, winnr('$'))
717 call assert_equal('Xxx1', bufname(winbufnr(winnr('$'))))
718 wincmd t
719
720 au! BufReadPost
721 %bwipe!
722 call delete('Xxx1')
723 call delete('Xxx2')
724 call delete('Xxx3')
725 enew! | only
726endfunc
727
728" Test for autocommand that changes current buffer on BufEnter event.
729" Check if modelines are interpreted for the correct buffer.
730func Test_Acmd_BufEnter()
731 %bwipe!
732 call writefile(['start of test file Xxx1',
733 \ "\<Tab>this is a test",
734 \ 'end of test file Xxx1'], 'Xxx1')
735 call writefile(['start of test file Xxx2',
736 \ 'vim: set noai :',
737 \ "\<Tab>this is a test",
738 \ 'end of test file Xxx2'], 'Xxx2')
739
740 au BufEnter Xxx2 brew
741 set ai modeline modelines=3
742 edit Xxx1
743 " edit Xxx2, autocmd will do :brew
744 edit Xxx2
745 exe "normal G?this is a\<CR>"
746 " Append text with autoindent to this file
747 normal othis should be auto-indented
748 call assert_equal("\<Tab>this should be auto-indented", getline('.'))
749 call assert_equal(3, line('.'))
750 " Remove autocmd and edit Xxx2 again
751 au! BufEnter Xxx2
752 buf! Xxx2
753 exe "normal G?this is a\<CR>"
754 " append text without autoindent to Xxx
755 normal othis should be in column 1
756 call assert_equal("this should be in column 1", getline('.'))
757 call assert_equal(4, line('.'))
758
759 %bwipe!
760 call delete('Xxx1')
761 call delete('Xxx2')
762 set ai&vim modeline&vim modelines&vim
763endfunc
764
765" Test for issue #57
766" do not move cursor on <c-o> when autoindent is set
767func Test_ai_CTRL_O()
768 enew!
769 set ai
770 let save_fo = &fo
771 set fo+=r
772 exe "normal o# abcdef\<Esc>2hi\<CR>\<C-O>d0\<Esc>"
773 exe "normal o# abcdef\<Esc>2hi\<C-O>d0\<Esc>"
774 call assert_equal(['# abc', 'def', 'def'], getline(2, 4))
775
776 set ai&vim
777 let &fo = save_fo
778 enew!
779endfunc
780
781" Test for autocommand that deletes the current buffer on BufLeave event.
782" Also test deleting the last buffer, should give a new, empty buffer.
783func Test_BufLeave_Wipe()
784 %bwipe!
785 let content = ['start of test file Xxx',
786 \ 'this is a test',
787 \ 'end of test file Xxx']
788 call writefile(content, 'Xxx1')
789 call writefile(content, 'Xxx2')
790
791 au BufLeave Xxx2 bwipe
792 edit Xxx1
793 split Xxx2
794 " delete buffer Xxx2, we should be back to Xxx1
795 bwipe
796 call assert_equal('Xxx1', bufname('%'))
797 call assert_equal(1, winnr('$'))
798
799 " Create an alternate buffer
800 %write! test.out
801 call assert_equal('test.out', bufname('#'))
802 " delete alternate buffer
803 bwipe test.out
804 call assert_equal('Xxx1', bufname('%'))
805 call assert_equal('', bufname('#'))
806
807 au BufLeave Xxx1 bwipe
808 " delete current buffer, get an empty one
809 bwipe!
810 call assert_equal(1, line('$'))
811 call assert_equal('', bufname('%'))
Bram Moolenaarb2c87502017-10-14 21:15:58 +0200812 let g:bufinfo = getbufinfo()
813 call assert_equal(1, len(g:bufinfo))
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +0200814
815 call delete('Xxx1')
816 call delete('Xxx2')
Bram Moolenaar53f0c962017-10-22 14:23:59 +0200817 call delete('test.out')
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +0200818 %bwipe
819 au! BufLeave
Bram Moolenaarb2c87502017-10-14 21:15:58 +0200820
821 " check that bufinfo doesn't contain a pointer to freed memory
822 call test_garbagecollect_now()
Bram Moolenaar4a6fcf82017-10-12 21:29:22 +0200823endfunc
Bram Moolenaar87ffb5c2017-10-19 12:37:42 +0200824
825func Test_QuitPre()
826 edit Xfoo
827 let winid = win_getid(winnr())
828 split Xbar
829 au! QuitPre * let g:afile = expand('<afile>')
830 " Close the other window, <afile> should be correct.
831 exe win_id2win(winid) . 'q'
832 call assert_equal('Xfoo', g:afile)
833
834 unlet g:afile
835 bwipe Xfoo
836 bwipe Xbar
837endfunc
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +0200838
839func Test_Cmdline()
Bram Moolenaar153b7042018-01-31 15:48:32 +0100840 au! CmdlineChanged : let g:text = getcmdline()
841 let g:text = 0
842 call feedkeys(":echom 'hello'\<CR>", 'xt')
843 call assert_equal("echom 'hello'", g:text)
844 au! CmdlineChanged
845
846 au! CmdlineChanged : let g:entered = expand('<afile>')
847 let g:entered = 0
848 call feedkeys(":echom 'hello'\<CR>", 'xt')
849 call assert_equal(':', g:entered)
850 au! CmdlineChanged
851
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +0200852 au! CmdlineEnter : let g:entered = expand('<afile>')
853 au! CmdlineLeave : let g:left = expand('<afile>')
854 let g:entered = 0
855 let g:left = 0
856 call feedkeys(":echo 'hello'\<CR>", 'xt')
857 call assert_equal(':', g:entered)
858 call assert_equal(':', g:left)
859 au! CmdlineEnter
860 au! CmdlineLeave
861
Bram Moolenaara4baf5b2018-04-22 13:27:44 +0200862 let save_shellslash = &shellslash
863 set noshellslash
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +0200864 au! CmdlineEnter / let g:entered = expand('<afile>')
865 au! CmdlineLeave / let g:left = expand('<afile>')
866 let g:entered = 0
867 let g:left = 0
Bram Moolenaar53f0c962017-10-22 14:23:59 +0200868 new
869 call setline(1, 'hello')
870 call feedkeys("/hello\<CR>", 'xt')
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +0200871 call assert_equal('/', g:entered)
872 call assert_equal('/', g:left)
Bram Moolenaar53f0c962017-10-22 14:23:59 +0200873 bwipe!
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +0200874 au! CmdlineEnter
875 au! CmdlineLeave
Bram Moolenaara4baf5b2018-04-22 13:27:44 +0200876 let &shellslash = save_shellslash
Bram Moolenaarfafcf0d2017-10-19 18:35:51 +0200877endfunc
Bram Moolenaar53f0c962017-10-22 14:23:59 +0200878
879" Test for BufWritePre autocommand that deletes or unloads the buffer.
880func Test_BufWritePre()
881 %bwipe
882 au BufWritePre Xxx1 bunload
883 au BufWritePre Xxx2 bwipe
884
885 call writefile(['start of Xxx1', 'test', 'end of Xxx1'], 'Xxx1')
886 call writefile(['start of Xxx2', 'test', 'end of Xxx2'], 'Xxx2')
887
888 edit Xtest
889 e! Xxx2
890 bdel Xtest
891 e Xxx1
892 " write it, will unload it and give an error msg
893 call assert_fails('w', 'E203')
894 call assert_equal('Xxx2', bufname('%'))
895 edit Xtest
896 e! Xxx2
897 bwipe Xtest
898 " write it, will delete the buffer and give an error msg
899 call assert_fails('w', 'E203')
900 call assert_equal('Xxx1', bufname('%'))
901 au! BufWritePre
902 call delete('Xxx1')
903 call delete('Xxx2')
904endfunc
905
906" Test for BufUnload autocommand that unloads all the other buffers
907func Test_bufunload_all()
908 call writefile(['Test file Xxx1'], 'Xxx1')"
909 call writefile(['Test file Xxx2'], 'Xxx2')"
910
911 let content = [
912 \ "func UnloadAllBufs()",
913 \ " let i = 1",
914 \ " while i <= bufnr('$')",
915 \ " if i != bufnr('%') && bufloaded(i)",
916 \ " exe i . 'bunload'",
917 \ " endif",
918 \ " let i += 1",
919 \ " endwhile",
920 \ "endfunc",
921 \ "au BufUnload * call UnloadAllBufs()",
922 \ "au VimLeave * call writefile(['Test Finished'], 'Xout')",
923 \ "edit Xxx1",
924 \ "split Xxx2",
925 \ "q"]
926 call writefile(content, 'Xtest')
927
928 call delete('Xout')
929 call system(v:progpath. ' --clean -N --not-a-term -S Xtest')
930 call assert_true(filereadable('Xout'))
931
932 call delete('Xxx1')
933 call delete('Xxx2')
934 call delete('Xtest')
935 call delete('Xout')
936endfunc
937
938" Some tests for buffer-local autocommands
939func Test_buflocal_autocmd()
940 let g:bname = ''
941 edit xx
942 au BufLeave <buffer> let g:bname = expand("%")
943 " here, autocommand for xx should trigger.
944 " but autocommand shall not apply to buffer named <buffer>.
945 edit somefile
946 call assert_equal('xx', g:bname)
947 let g:bname = ''
948 " here, autocommand shall be auto-deleted
949 bwipe xx
950 " autocmd should not trigger
951 edit xx
952 call assert_equal('', g:bname)
953 " autocmd should not trigger
954 edit somefile
955 call assert_equal('', g:bname)
956 enew
957 unlet g:bname
958endfunc
Bram Moolenaar430dc5d2017-11-02 21:04:47 +0100959
960" Test for "*Cmd" autocommands
961func Test_Cmd_Autocmds()
962 call writefile(['start of Xxx', "\tabc2", 'end of Xxx'], 'Xxx')
963
964 enew!
965 au BufReadCmd XtestA 0r Xxx|$del
966 edit XtestA " will read text of Xxd instead
967 call assert_equal('start of Xxx', getline(1))
968
969 au BufWriteCmd XtestA call append(line("$"), "write")
970 write " will append a line to the file
971 call assert_equal('write', getline('$'))
972 call assert_fails('read XtestA', 'E484') " should not read anything
973 call assert_equal('write', getline(4))
974
975 " now we have:
976 " 1 start of Xxx
977 " 2 abc2
978 " 3 end of Xxx
979 " 4 write
980
981 au FileReadCmd XtestB '[r Xxx
982 2r XtestB " will read Xxx below line 2 instead
983 call assert_equal('start of Xxx', getline(3))
984
985 " now we have:
986 " 1 start of Xxx
987 " 2 abc2
988 " 3 start of Xxx
989 " 4 abc2
990 " 5 end of Xxx
991 " 6 end of Xxx
992 " 7 write
993
994 au FileWriteCmd XtestC '[,']copy $
995 normal 4GA1
996 4,5w XtestC " will copy lines 4 and 5 to the end
997 call assert_equal("\tabc21", getline(8))
998 call assert_fails('r XtestC', 'E484') " should not read anything
999 call assert_equal("end of Xxx", getline(9))
1000
1001 " now we have:
1002 " 1 start of Xxx
1003 " 2 abc2
1004 " 3 start of Xxx
1005 " 4 abc21
1006 " 5 end of Xxx
1007 " 6 end of Xxx
1008 " 7 write
1009 " 8 abc21
1010 " 9 end of Xxx
1011
1012 let g:lines = []
1013 au FileAppendCmd XtestD call extend(g:lines, getline(line("'["), line("']")))
1014 w >>XtestD " will add lines to 'lines'
1015 call assert_equal(9, len(g:lines))
1016 call assert_fails('$r XtestD', 'E484') " should not read anything
1017 call assert_equal(9, line('$'))
1018 call assert_equal('end of Xxx', getline('$'))
1019
1020 au BufReadCmd XtestE 0r Xxx|$del
1021 sp XtestE " split window with test.out
1022 call assert_equal('end of Xxx', getline(3))
1023
1024 let g:lines = []
1025 exe "normal 2Goasdf\<Esc>\<C-W>\<C-W>"
1026 au BufWriteCmd XtestE call extend(g:lines, getline(0, '$'))
1027 wall " will write other window to 'lines'
1028 call assert_equal(4, len(g:lines), g:lines)
1029 call assert_equal('asdf', g:lines[2])
1030
1031 au! BufReadCmd
1032 au! BufWriteCmd
1033 au! FileReadCmd
1034 au! FileWriteCmd
1035 au! FileAppendCmd
1036 %bwipe!
1037 call delete('Xxx')
1038 enew!
1039endfunc
Bram Moolenaaraace2152017-11-05 16:23:10 +01001040
1041func SetChangeMarks(start, end)
1042 exe a:start. 'mark ['
1043 exe a:end. 'mark ]'
1044endfunc
1045
1046" Verify the effects of autocmds on '[ and ']
1047func Test_change_mark_in_autocmds()
1048 edit! Xtest
1049 call feedkeys("ia\<CR>b\<CR>c\<CR>d\<C-g>u", 'xtn')
1050
1051 call SetChangeMarks(2, 3)
1052 write
1053 call assert_equal([1, 4], [line("'["), line("']")])
1054
1055 call SetChangeMarks(2, 3)
1056 au BufWritePre * call assert_equal([1, 4], [line("'["), line("']")])
1057 write
1058 au! BufWritePre
1059
1060 if executable('cat')
1061 write XtestFilter
1062 write >> XtestFilter
1063
1064 call SetChangeMarks(2, 3)
1065 " Marks are set to the entire range of the write
1066 au FilterWritePre * call assert_equal([1, 4], [line("'["), line("']")])
1067 " '[ is adjusted to just before the line that will receive the filtered
1068 " data
1069 au FilterReadPre * call assert_equal([4, 4], [line("'["), line("']")])
1070 " The filtered data is read into the buffer, and the source lines are
1071 " still present, so the range is after the source lines
1072 au FilterReadPost * call assert_equal([5, 12], [line("'["), line("']")])
1073 %!cat XtestFilter
1074 " After the filtered data is read, the original lines are deleted
1075 call assert_equal([1, 8], [line("'["), line("']")])
1076 au! FilterWritePre,FilterReadPre,FilterReadPost
1077 undo
1078
1079 call SetChangeMarks(1, 4)
1080 au FilterWritePre * call assert_equal([2, 3], [line("'["), line("']")])
1081 au FilterReadPre * call assert_equal([3, 3], [line("'["), line("']")])
1082 au FilterReadPost * call assert_equal([4, 11], [line("'["), line("']")])
1083 2,3!cat XtestFilter
1084 call assert_equal([2, 9], [line("'["), line("']")])
1085 au! FilterWritePre,FilterReadPre,FilterReadPost
1086 undo
1087
1088 call delete('XtestFilter')
1089 endif
1090
1091 call SetChangeMarks(1, 4)
1092 au FileWritePre * call assert_equal([2, 3], [line("'["), line("']")])
1093 2,3write Xtest2
1094 au! FileWritePre
1095
1096 call SetChangeMarks(2, 3)
1097 au FileAppendPre * call assert_equal([1, 4], [line("'["), line("']")])
1098 write >> Xtest2
1099 au! FileAppendPre
1100
1101 call SetChangeMarks(1, 4)
1102 au FileAppendPre * call assert_equal([2, 3], [line("'["), line("']")])
1103 2,3write >> Xtest2
1104 au! FileAppendPre
1105
1106 call SetChangeMarks(1, 1)
1107 au FileReadPre * call assert_equal([3, 1], [line("'["), line("']")])
1108 au FileReadPost * call assert_equal([4, 11], [line("'["), line("']")])
1109 3read Xtest2
1110 au! FileReadPre,FileReadPost
1111 undo
1112
1113 call SetChangeMarks(4, 4)
1114 " When the line is 0, it's adjusted to 1
1115 au FileReadPre * call assert_equal([1, 4], [line("'["), line("']")])
1116 au FileReadPost * call assert_equal([1, 8], [line("'["), line("']")])
1117 0read Xtest2
1118 au! FileReadPre,FileReadPost
1119 undo
1120
1121 call SetChangeMarks(4, 4)
1122 " When the line is 0, it's adjusted to 1
1123 au FileReadPre * call assert_equal([1, 4], [line("'["), line("']")])
1124 au FileReadPost * call assert_equal([2, 9], [line("'["), line("']")])
1125 1read Xtest2
1126 au! FileReadPre,FileReadPost
1127 undo
1128
1129 bwipe!
1130 call delete('Xtest')
1131 call delete('Xtest2')
1132endfunc
1133
1134func Test_Filter_noshelltemp()
1135 if !executable('cat')
1136 return
1137 endif
1138
1139 enew!
1140 call setline(1, ['a', 'b', 'c', 'd'])
1141
1142 let shelltemp = &shelltemp
1143 set shelltemp
1144
1145 let g:filter_au = 0
1146 au FilterWritePre * let g:filter_au += 1
1147 au FilterReadPre * let g:filter_au += 1
1148 au FilterReadPost * let g:filter_au += 1
1149 %!cat
1150 call assert_equal(3, g:filter_au)
1151
1152 if has('filterpipe')
1153 set noshelltemp
1154
1155 let g:filter_au = 0
1156 au FilterWritePre * let g:filter_au += 1
1157 au FilterReadPre * let g:filter_au += 1
1158 au FilterReadPost * let g:filter_au += 1
1159 %!cat
1160 call assert_equal(0, g:filter_au)
1161 endif
1162
1163 au! FilterWritePre,FilterReadPre,FilterReadPost
1164 let &shelltemp = shelltemp
1165 bwipe!
1166endfunc
Bram Moolenaar7e1652c2017-12-16 18:27:02 +01001167
1168func Test_TextYankPost()
1169 enew!
1170 call setline(1, ['foo'])
1171
1172 let g:event = []
1173 au TextYankPost * let g:event = copy(v:event)
1174
1175 call assert_equal({}, v:event)
1176 call assert_fails('let v:event = {}', 'E46:')
1177 call assert_fails('let v:event.mykey = 0', 'E742:')
1178
1179 norm "ayiw
1180 call assert_equal(
1181 \{'regcontents': ['foo'], 'regname': 'a', 'operator': 'y', 'regtype': 'v'},
1182 \g:event)
1183 norm y_
1184 call assert_equal(
1185 \{'regcontents': ['foo'], 'regname': '', 'operator': 'y', 'regtype': 'V'},
1186 \g:event)
1187 call feedkeys("\<C-V>y", 'x')
1188 call assert_equal(
1189 \{'regcontents': ['f'], 'regname': '', 'operator': 'y', 'regtype': "\x161"},
1190 \g:event)
1191 norm "xciwbar
1192 call assert_equal(
1193 \{'regcontents': ['foo'], 'regname': 'x', 'operator': 'c', 'regtype': 'v'},
1194 \g:event)
1195 norm "bdiw
1196 call assert_equal(
1197 \{'regcontents': ['bar'], 'regname': 'b', 'operator': 'd', 'regtype': 'v'},
1198 \g:event)
1199
1200 call assert_equal({}, v:event)
1201
1202 au! TextYankPost
1203 unlet g:event
1204 bwipe!
1205endfunc
Bram Moolenaar9bca8052017-12-18 12:37:55 +01001206
1207func Test_nocatch_wipe_all_buffers()
1208 " Real nasty autocommand: wipe all buffers on any event.
1209 au * * bwipe *
Bram Moolenaara997b452018-04-17 23:24:06 +02001210 " Get E93 first?
1211 " call assert_fails('next x', 'E93:')
1212 call assert_fails('next x', 'E517:')
Bram Moolenaar9bca8052017-12-18 12:37:55 +01001213 bwipe
1214 au!
1215endfunc
Bram Moolenaar4fb921e2017-12-18 15:33:00 +01001216
1217func Test_nocatch_wipe_dummy_buffer()
1218 " Nasty autocommand: wipe buffer on any event.
1219 au * x bwipe
1220 call assert_fails('lv½ /x', 'E480')
1221 au!
1222endfunc
Bram Moolenaarb7407d32018-02-03 17:36:27 +01001223
1224function s:Before_test_dirchanged()
1225 augroup test_dirchanged
1226 autocmd!
1227 augroup END
1228 let s:li = []
1229 let s:dir_this = getcwd()
Bram Moolenaar2caad3f2018-12-16 15:38:02 +01001230 let s:dir_foo = s:dir_this . '/foo'
1231 call mkdir(s:dir_foo)
1232 let s:dir_bar = s:dir_this . '/bar'
1233 call mkdir(s:dir_bar)
Bram Moolenaarb7407d32018-02-03 17:36:27 +01001234endfunc
1235
1236function s:After_test_dirchanged()
1237 exe 'cd' s:dir_this
Bram Moolenaar2caad3f2018-12-16 15:38:02 +01001238 call delete(s:dir_foo, 'd')
1239 call delete(s:dir_bar, 'd')
Bram Moolenaarb7407d32018-02-03 17:36:27 +01001240 augroup test_dirchanged
1241 autocmd!
1242 augroup END
1243endfunc
1244
1245function Test_dirchanged_global()
1246 call s:Before_test_dirchanged()
1247 autocmd test_dirchanged DirChanged global call add(s:li, "cd:")
1248 autocmd test_dirchanged DirChanged global call add(s:li, expand("<afile>"))
Bram Moolenaar2caad3f2018-12-16 15:38:02 +01001249 exe 'cd' s:dir_foo
1250 call assert_equal(["cd:", s:dir_foo], s:li)
1251 exe 'cd' s:dir_foo
1252 call assert_equal(["cd:", s:dir_foo], s:li)
1253 exe 'lcd' s:dir_bar
1254 call assert_equal(["cd:", s:dir_foo], s:li)
Bram Moolenaarb7407d32018-02-03 17:36:27 +01001255 call s:After_test_dirchanged()
1256endfunc
1257
1258function Test_dirchanged_local()
1259 call s:Before_test_dirchanged()
1260 autocmd test_dirchanged DirChanged window call add(s:li, "lcd:")
1261 autocmd test_dirchanged DirChanged window call add(s:li, expand("<afile>"))
Bram Moolenaar2caad3f2018-12-16 15:38:02 +01001262 exe 'cd' s:dir_foo
Bram Moolenaarb7407d32018-02-03 17:36:27 +01001263 call assert_equal([], s:li)
Bram Moolenaar2caad3f2018-12-16 15:38:02 +01001264 exe 'lcd' s:dir_bar
1265 call assert_equal(["lcd:", s:dir_bar], s:li)
1266 exe 'lcd' s:dir_bar
1267 call assert_equal(["lcd:", s:dir_bar], s:li)
Bram Moolenaarb7407d32018-02-03 17:36:27 +01001268 call s:After_test_dirchanged()
1269endfunc
1270
1271function Test_dirchanged_auto()
Bram Moolenaarec48a9c2018-02-03 20:11:40 +01001272 if !exists('+autochdir')
1273 return
1274 endif
Bram Moolenaarb7407d32018-02-03 17:36:27 +01001275 call s:Before_test_dirchanged()
1276 call test_autochdir()
1277 autocmd test_dirchanged DirChanged auto call add(s:li, "auto:")
1278 autocmd test_dirchanged DirChanged auto call add(s:li, expand("<afile>"))
1279 set acd
1280 exe 'cd ..'
1281 call assert_equal([], s:li)
Bram Moolenaar2caad3f2018-12-16 15:38:02 +01001282 exe 'edit ' . s:dir_foo . '/Xfile'
1283 call assert_equal(s:dir_foo, getcwd())
1284 call assert_equal(["auto:", s:dir_foo], s:li)
Bram Moolenaarb7407d32018-02-03 17:36:27 +01001285 set noacd
1286 bwipe!
1287 call s:After_test_dirchanged()
1288endfunc
Bram Moolenaar5a093432018-02-10 18:15:19 +01001289
1290" Test TextChangedI and TextChangedP
1291func Test_ChangedP()
1292 new
1293 call setline(1, ['foo', 'bar', 'foobar'])
1294 call test_override("char_avail", 1)
1295 set complete=. completeopt=menuone
1296
1297 func! TextChangedAutocmd(char)
1298 let g:autocmd .= a:char
1299 endfunc
1300
1301 au! TextChanged <buffer> :call TextChangedAutocmd('N')
1302 au! TextChangedI <buffer> :call TextChangedAutocmd('I')
1303 au! TextChangedP <buffer> :call TextChangedAutocmd('P')
1304
1305 call cursor(3, 1)
1306 let g:autocmd = ''
1307 call feedkeys("o\<esc>", 'tnix')
1308 call assert_equal('I', g:autocmd)
1309
1310 let g:autocmd = ''
1311 call feedkeys("Sf", 'tnix')
1312 call assert_equal('II', g:autocmd)
1313
1314 let g:autocmd = ''
1315 call feedkeys("Sf\<C-N>", 'tnix')
1316 call assert_equal('IIP', g:autocmd)
1317
1318 let g:autocmd = ''
1319 call feedkeys("Sf\<C-N>\<C-N>", 'tnix')
1320 call assert_equal('IIPP', g:autocmd)
1321
1322 let g:autocmd = ''
1323 call feedkeys("Sf\<C-N>\<C-N>\<C-N>", 'tnix')
1324 call assert_equal('IIPPP', g:autocmd)
1325
1326 let g:autocmd = ''
1327 call feedkeys("Sf\<C-N>\<C-N>\<C-N>\<C-N>", 'tnix')
1328 call assert_equal('IIPPPP', g:autocmd)
1329
1330 call assert_equal(['foo', 'bar', 'foobar', 'foo'], getline(1, '$'))
1331 " TODO: how should it handle completeopt=noinsert,noselect?
1332
1333 " CleanUp
1334 call test_override("char_avail", 0)
1335 au! TextChanged
1336 au! TextChangedI
1337 au! TextChangedP
1338 delfu TextChangedAutocmd
1339 unlet! g:autocmd
1340 set complete&vim completeopt&vim
1341
1342 bw!
1343endfunc
Bram Moolenaar8c64a362018-03-23 22:39:31 +01001344
Bram Moolenaar91d2e782018-08-07 19:05:01 +02001345let g:setline_handled = v:false
Bram Moolenaar1e115362019-01-09 23:01:02 +01001346func SetLineOne()
Bram Moolenaar91d2e782018-08-07 19:05:01 +02001347 if !g:setline_handled
1348 call setline(1, "(x)")
1349 let g:setline_handled = v:true
1350 endif
1351endfunc
1352
1353func Test_TextChangedI_with_setline()
1354 new
1355 call test_override('char_avail', 1)
1356 autocmd TextChangedI <buffer> call SetLineOne()
1357 call feedkeys("i(\<CR>\<Esc>", 'tx')
1358 call assert_equal('(', getline(1))
1359 call assert_equal('x)', getline(2))
1360 undo
Bram Moolenaar91d2e782018-08-07 19:05:01 +02001361 call assert_equal('', getline(1))
Bram Moolenaar9fa95062018-08-08 22:08:32 +02001362 call assert_equal('', getline(2))
Bram Moolenaar91d2e782018-08-07 19:05:01 +02001363
1364 call test_override('starting', 0)
1365 bwipe!
1366endfunc
1367
Bram Moolenaar8c64a362018-03-23 22:39:31 +01001368func Test_Changed_FirstTime()
1369 if !has('terminal') || has('gui_running')
1370 return
1371 endif
1372 " Prepare file for TextChanged event.
1373 call writefile([''], 'Xchanged.txt')
1374 let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3})
1375 call assert_equal('running', term_getstatus(buf))
Bram Moolenaar1834d372018-03-29 17:40:46 +02001376 " Wait for the ruler (in the status line) to be shown.
Bram Moolenaar50182fa2018-04-28 21:34:40 +02001377 call WaitForAssert({-> assert_match('\<All$', term_getline(buf, 3))})
Bram Moolenaar8c64a362018-03-23 22:39:31 +01001378 " It's only adding autocmd, so that no event occurs.
1379 call term_sendkeys(buf, ":au! TextChanged <buffer> call writefile(['No'], 'Xchanged.txt')\<cr>")
1380 call term_sendkeys(buf, "\<C-\\>\<C-N>:qa!\<cr>")
Bram Moolenaar50182fa2018-04-28 21:34:40 +02001381 call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))})
Bram Moolenaar8c64a362018-03-23 22:39:31 +01001382 call assert_equal([''], readfile('Xchanged.txt'))
1383
1384 " clean up
1385 call delete('Xchanged.txt')
1386 bwipe!
1387endfunc
Bram Moolenaar0566e892019-01-24 19:37:40 +01001388
1389func Test_FileChangedShell_reload()
1390 if !has('unix')
1391 return
1392 endif
1393 augroup testreload
1394 au FileChangedShell Xchanged let g:reason = v:fcs_reason | let v:fcs_choice = 'reload'
1395 augroup END
1396 new Xchanged
1397 call setline(1, 'reload this')
1398 write
1399 " Need to wait until the timestamp would change by at least a second.
1400 sleep 2
1401 silent !echo 'extra line' >>Xchanged
1402 checktime
1403 call assert_equal('changed', g:reason)
1404 call assert_equal(2, line('$'))
1405 call assert_equal('extra line', getline(2))
1406
1407 " Only triggers once
1408 let g:reason = ''
1409 checktime
1410 call assert_equal('', g:reason)
1411
1412 " When deleted buffer is not reloaded
1413 silent !rm Xchanged
1414 let g:reason = ''
1415 checktime
1416 call assert_equal('deleted', g:reason)
1417 call assert_equal(2, line('$'))
1418 call assert_equal('extra line', getline(2))
1419
1420 " When recreated buffer is reloaded
1421 call setline(1, 'buffer is changed')
1422 silent !echo 'new line' >>Xchanged
1423 let g:reason = ''
1424 checktime
1425 call assert_equal('conflict', g:reason)
1426 call assert_equal(1, line('$'))
1427 call assert_equal('new line', getline(1))
1428
1429 " Only mode changed
1430 silent !chmod +x Xchanged
1431 let g:reason = ''
1432 checktime
1433 call assert_equal('mode', g:reason)
1434 call assert_equal(1, line('$'))
1435 call assert_equal('new line', getline(1))
1436
1437 " Only time changed
1438 sleep 2
1439 silent !touch Xchanged
1440 let g:reason = ''
1441 checktime
1442 call assert_equal('time', g:reason)
1443 call assert_equal(1, line('$'))
1444 call assert_equal('new line', getline(1))
1445
1446 if has('persistent_undo')
1447 " With an undo file the reload can be undone and a change before the
1448 " reload.
1449 set undofile
1450 call setline(2, 'before write')
1451 write
1452 call setline(2, 'after write')
1453 sleep 2
1454 silent !echo 'different line' >>Xchanged
1455 let g:reason = ''
1456 checktime
1457 call assert_equal('conflict', g:reason)
1458 call assert_equal(3, line('$'))
1459 call assert_equal('before write', getline(2))
1460 call assert_equal('different line', getline(3))
1461 " undo the reload
1462 undo
1463 call assert_equal(2, line('$'))
1464 call assert_equal('after write', getline(2))
1465 " undo the change before reload
1466 undo
1467 call assert_equal(2, line('$'))
1468 call assert_equal('before write', getline(2))
1469
1470 set noundofile
1471 endif
1472
1473
1474 au! testreload
1475 bwipe!
1476 call delete('Xchanged')
1477endfunc