xref: /vim-8.2.3635/src/testdir/test_autocmd.vim (revision ed37d9b3)
1" Tests for autocommands
2
3source shared.vim
4source check.vim
5source term_util.vim
6
7func s:cleanup_buffers() abort
8  for bnr in range(1, bufnr('$'))
9    if bufloaded(bnr) && bufnr('%') != bnr
10      execute 'bd! ' . bnr
11    endif
12  endfor
13endfunc
14
15func Test_vim_did_enter()
16  call assert_false(v:vim_did_enter)
17
18  " This script will never reach the main loop, can't check if v:vim_did_enter
19  " becomes one.
20endfunc
21
22if has('timers')
23
24  func ExitInsertMode(id)
25    call feedkeys("\<Esc>")
26  endfunc
27
28  func Test_cursorhold_insert()
29    " Need to move the cursor.
30    call feedkeys("ggG", "xt")
31
32    let g:triggered = 0
33    au CursorHoldI * let g:triggered += 1
34    set updatetime=20
35    call timer_start(100, 'ExitInsertMode')
36    call feedkeys('a', 'x!')
37    call assert_equal(1, g:triggered)
38    unlet g:triggered
39    au! CursorHoldI
40    set updatetime&
41  endfunc
42
43  func Test_cursorhold_insert_with_timer_interrupt()
44    if !has('job')
45      return
46    endif
47    " Need to move the cursor.
48    call feedkeys("ggG", "xt")
49
50    " Confirm the timer invoked in exit_cb of the job doesn't disturb
51    " CursorHoldI event.
52    let g:triggered = 0
53    au CursorHoldI * let g:triggered += 1
54    set updatetime=500
55    call job_start(has('win32') ? 'cmd /c echo:' : 'echo',
56          \ {'exit_cb': {-> timer_start(1000, 'ExitInsertMode')}})
57    call feedkeys('a', 'x!')
58    call assert_equal(1, g:triggered)
59    unlet g:triggered
60    au! CursorHoldI
61    set updatetime&
62  endfunc
63
64  func Test_cursorhold_insert_ctrl_x()
65    let g:triggered = 0
66    au CursorHoldI * let g:triggered += 1
67    set updatetime=20
68    call timer_start(100, 'ExitInsertMode')
69    " CursorHoldI does not trigger after CTRL-X
70    call feedkeys("a\<C-X>", 'x!')
71    call assert_equal(0, g:triggered)
72    unlet g:triggered
73    au! CursorHoldI
74    set updatetime&
75  endfunc
76
77  func Test_OptionSet_modeline()
78    call test_override('starting', 1)
79    au! OptionSet
80    augroup set_tabstop
81      au OptionSet tabstop call timer_start(1, {-> execute("echo 'Handler called'", "")})
82    augroup END
83    call writefile(['vim: set ts=7 sw=5 :', 'something'], 'XoptionsetModeline')
84    set modeline
85    let v:errmsg = ''
86    call assert_fails('split XoptionsetModeline', 'E12:')
87    call assert_equal(7, &ts)
88    call assert_equal('', v:errmsg)
89
90    augroup set_tabstop
91      au!
92    augroup END
93    bwipe!
94    set ts&
95    call delete('XoptionsetModeline')
96    call test_override('starting', 0)
97  endfunc
98
99endif "has('timers')
100
101func Test_bufunload()
102  augroup test_bufunload_group
103    autocmd!
104    autocmd BufUnload * call add(s:li, "bufunload")
105    autocmd BufDelete * call add(s:li, "bufdelete")
106    autocmd BufWipeout * call add(s:li, "bufwipeout")
107  augroup END
108
109  let s:li=[]
110  new
111  setlocal bufhidden=
112  bunload
113  call assert_equal(["bufunload", "bufdelete"], s:li)
114
115  let s:li=[]
116  new
117  setlocal bufhidden=delete
118  bunload
119  call assert_equal(["bufunload", "bufdelete"], s:li)
120
121  let s:li=[]
122  new
123  setlocal bufhidden=unload
124  bwipeout
125  call assert_equal(["bufunload", "bufdelete", "bufwipeout"], s:li)
126
127  au! test_bufunload_group
128  augroup! test_bufunload_group
129endfunc
130
131" SEGV occurs in older versions.  (At least 7.4.2005 or older)
132func Test_autocmd_bufunload_with_tabnext()
133  tabedit
134  tabfirst
135
136  augroup test_autocmd_bufunload_with_tabnext_group
137    autocmd!
138    autocmd BufUnload <buffer> tabnext
139  augroup END
140
141  quit
142  call assert_equal(2, tabpagenr('$'))
143
144  autocmd! test_autocmd_bufunload_with_tabnext_group
145  augroup! test_autocmd_bufunload_with_tabnext_group
146  tablast
147  quit
148endfunc
149
150func Test_autocmd_bufwinleave_with_tabfirst()
151  tabedit
152  augroup sample
153    autocmd!
154    autocmd BufWinLeave <buffer> tabfirst
155  augroup END
156  call setline(1, ['a', 'b', 'c'])
157  edit! a.txt
158  tabclose
159endfunc
160
161" SEGV occurs in older versions.  (At least 7.4.2321 or older)
162func Test_autocmd_bufunload_avoiding_SEGV_01()
163  split aa.txt
164  let lastbuf = bufnr('$')
165
166  augroup test_autocmd_bufunload
167    autocmd!
168    exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!'
169  augroup END
170
171  " Todo: check for E937 generated first
172  " call assert_fails('edit bb.txt', 'E937:')
173  call assert_fails('edit bb.txt', 'E517:')
174
175  autocmd! test_autocmd_bufunload
176  augroup! test_autocmd_bufunload
177  bwipe! aa.txt
178  bwipe! bb.txt
179endfunc
180
181" SEGV occurs in older versions.  (At least 7.4.2321 or older)
182func Test_autocmd_bufunload_avoiding_SEGV_02()
183  setlocal buftype=nowrite
184  let lastbuf = bufnr('$')
185
186  augroup test_autocmd_bufunload
187    autocmd!
188    exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!'
189  augroup END
190
191  normal! i1
192  call assert_fails('edit a.txt', 'E517:')
193  call feedkeys("\<CR>")
194
195  autocmd! test_autocmd_bufunload
196  augroup! test_autocmd_bufunload
197  bwipe! a.txt
198endfunc
199
200func Test_win_tab_autocmd()
201  let g:record = []
202
203  augroup testing
204    au WinNew * call add(g:record, 'WinNew')
205    au WinEnter * call add(g:record, 'WinEnter')
206    au WinLeave * call add(g:record, 'WinLeave')
207    au TabNew * call add(g:record, 'TabNew')
208    au TabClosed * call add(g:record, 'TabClosed')
209    au TabEnter * call add(g:record, 'TabEnter')
210    au TabLeave * call add(g:record, 'TabLeave')
211  augroup END
212
213  split
214  tabnew
215  close
216  close
217
218  call assert_equal([
219	\ 'WinLeave', 'WinNew', 'WinEnter',
220	\ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
221	\ 'WinLeave', 'TabLeave', 'TabClosed', 'WinEnter', 'TabEnter',
222	\ 'WinLeave', 'WinEnter'
223	\ ], g:record)
224
225  let g:record = []
226  tabnew somefile
227  tabnext
228  bwipe somefile
229
230  call assert_equal([
231	\ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter',
232	\ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter',
233	\ 'TabClosed'
234	\ ], g:record)
235
236  augroup testing
237    au!
238  augroup END
239  unlet g:record
240endfunc
241
242func s:AddAnAutocmd()
243  augroup vimBarTest
244    au BufReadCmd * echo 'hello'
245  augroup END
246  call assert_equal(3, len(split(execute('au vimBarTest'), "\n")))
247endfunc
248
249func Test_early_bar()
250  " test that a bar is recognized before the {event}
251  call s:AddAnAutocmd()
252  augroup vimBarTest | au! | augroup END
253  call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
254
255  call s:AddAnAutocmd()
256  augroup vimBarTest| au!| augroup END
257  call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
258
259  " test that a bar is recognized after the {event}
260  call s:AddAnAutocmd()
261  augroup vimBarTest| au!BufReadCmd| augroup END
262  call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
263
264  " test that a bar is recognized after the {group}
265  call s:AddAnAutocmd()
266  au! vimBarTest|echo 'hello'
267  call assert_equal(1, len(split(execute('au vimBarTest'), "\n")))
268endfunc
269
270func RemoveGroup()
271  autocmd! StartOK
272  augroup! StartOK
273endfunc
274
275func Test_augroup_warning()
276  augroup TheWarning
277    au VimEnter * echo 'entering'
278  augroup END
279  call assert_true(match(execute('au VimEnter'), "TheWarning.*VimEnter") >= 0)
280  redir => res
281  augroup! TheWarning
282  redir END
283  call assert_true(match(res, "W19:") >= 0)
284  call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0)
285
286  " check "Another" does not take the pace of the deleted entry
287  augroup Another
288  augroup END
289  call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0)
290  augroup! Another
291
292  " no warning for postpone aucmd delete
293  augroup StartOK
294    au VimEnter * call RemoveGroup()
295  augroup END
296  call assert_true(match(execute('au VimEnter'), "StartOK.*VimEnter") >= 0)
297  redir => res
298  doautocmd VimEnter
299  redir END
300  call assert_true(match(res, "W19:") < 0)
301  au! VimEnter
302
303  call assert_fails('augroup!', 'E471:')
304endfunc
305
306func Test_BufReadCmdHelp()
307  " This used to cause access to free memory
308  au BufReadCmd * e +h
309  help
310
311  au! BufReadCmd
312endfunc
313
314func Test_BufReadCmdHelpJump()
315  " This used to cause access to free memory
316  au BufReadCmd * e +h{
317  " } to fix highlighting
318  call assert_fails('help', 'E434:')
319
320  au! BufReadCmd
321endfunc
322
323func Test_augroup_deleted()
324  " This caused a crash before E936 was introduced
325  augroup x
326    call assert_fails('augroup! x', 'E936:')
327    au VimEnter * echo
328  augroup end
329  augroup! x
330  call assert_true(match(execute('au VimEnter'), "-Deleted-.*VimEnter") >= 0)
331  au! VimEnter
332endfunc
333
334" Tests for autocommands on :close command.
335" This used to be in test13.
336func Test_three_windows()
337  " Clean up buffers, because in some cases this function fails.
338  call s:cleanup_buffers()
339
340  " Write three files and open them, each in a window.
341  " Then go to next window, with autocommand that deletes the previous one.
342  " Do this twice, writing the file.
343  e! Xtestje1
344  call setline(1, 'testje1')
345  w
346  sp Xtestje2
347  call setline(1, 'testje2')
348  w
349  sp Xtestje3
350  call setline(1, 'testje3')
351  w
352  wincmd w
353  au WinLeave Xtestje2 bwipe
354  wincmd w
355  call assert_equal('Xtestje1', expand('%'))
356
357  au WinLeave Xtestje1 bwipe Xtestje3
358  close
359  call assert_equal('Xtestje1', expand('%'))
360
361  " Test deleting the buffer on a Unload event.  If this goes wrong there
362  " will be the ATTENTION prompt.
363  e Xtestje1
364  au!
365  au! BufUnload Xtestje1 bwipe
366  call assert_fails('e Xtestje3', 'E937:')
367  call assert_equal('Xtestje3', expand('%'))
368
369  e Xtestje2
370  sp Xtestje1
371  call assert_fails('e', 'E937:')
372  call assert_equal('Xtestje1', expand('%'))
373
374  " Test changing buffers in a BufWipeout autocommand.  If this goes wrong
375  " there are ml_line errors and/or a Crash.
376  au!
377  only
378  e Xanother
379  e Xtestje1
380  bwipe Xtestje2
381  bwipe Xtestje3
382  au BufWipeout Xtestje1 buf Xtestje1
383  bwipe
384  call assert_equal('Xanother', expand('%'))
385
386  only
387  help
388  wincmd w
389  1quit
390  call assert_equal('Xanother', expand('%'))
391
392  au!
393  enew
394  call delete('Xtestje1')
395  call delete('Xtestje2')
396  call delete('Xtestje3')
397endfunc
398
399func Test_BufEnter()
400  au! BufEnter
401  au Bufenter * let val = val . '+'
402  let g:val = ''
403  split NewFile
404  call assert_equal('+', g:val)
405  bwipe!
406  call assert_equal('++', g:val)
407
408  " Also get BufEnter when editing a directory
409  call mkdir('Xdir')
410  split Xdir
411  call assert_equal('+++', g:val)
412
413  " On MS-Windows we can't edit the directory, make sure we wipe the right
414  " buffer.
415  bwipe! Xdir
416
417  call delete('Xdir', 'd')
418  au! BufEnter
419endfunc
420
421" Closing a window might cause an endless loop
422" E814 for older Vims
423func Test_autocmd_bufwipe_in_SessLoadPost()
424  edit Xtest
425  tabnew
426  file Xsomething
427  set noswapfile
428  mksession!
429
430  let content =<< trim [CODE]
431    set nocp noswapfile
432    let v:swapchoice="e"
433    augroup test_autocmd_sessionload
434    autocmd!
435    autocmd SessionLoadPost * exe bufnr("Xsomething") . "bw!"
436    augroup END
437
438    func WriteErrors()
439      call writefile([execute("messages")], "Xerrors")
440    endfunc
441    au VimLeave * call WriteErrors()
442  [CODE]
443
444  call writefile(content, 'Xvimrc')
445  call system(GetVimCommand('Xvimrc') .. ' --not-a-term --noplugins -S Session.vim -c cq')
446  let errors = join(readfile('Xerrors'))
447  call assert_match('E814', errors)
448
449  set swapfile
450  for file in ['Session.vim', 'Xvimrc', 'Xerrors']
451    call delete(file)
452  endfor
453endfunc
454
455" SEGV occurs in older versions.
456func Test_autocmd_bufwipe_in_SessLoadPost2()
457  tabnew
458  set noswapfile
459  mksession!
460
461  let content =<< trim [CODE]
462    set nocp noswapfile
463    function! DeleteInactiveBufs()
464      tabfirst
465      let tabblist = []
466      for i in range(1, tabpagenr(''$''))
467        call extend(tabblist, tabpagebuflist(i))
468      endfor
469      for b in range(1, bufnr(''$''))
470        if bufexists(b) && buflisted(b) && (index(tabblist, b) == -1 || bufname(b) =~# ''^$'')
471          exec ''bwipeout '' . b
472        endif
473      endfor
474      echomsg "SessionLoadPost DONE"
475    endfunction
476    au SessionLoadPost * call DeleteInactiveBufs()
477
478    func WriteErrors()
479      call writefile([execute("messages")], "Xerrors")
480    endfunc
481    au VimLeave * call WriteErrors()
482  [CODE]
483
484  call writefile(content, 'Xvimrc')
485  call system(GetVimCommand('Xvimrc') .. ' --not-a-term --noplugins -S Session.vim -c cq')
486  let errors = join(readfile('Xerrors'))
487  " This probably only ever matches on unix.
488  call assert_notmatch('Caught deadly signal SEGV', errors)
489  call assert_match('SessionLoadPost DONE', errors)
490
491  set swapfile
492  for file in ['Session.vim', 'Xvimrc', 'Xerrors']
493    call delete(file)
494  endfor
495endfunc
496
497func Test_empty_doau()
498  doau \|
499endfunc
500
501func s:AutoCommandOptionSet(match)
502  let template = "Option: <%s>, OldVal: <%s>, OldValLocal: <%s>, OldValGlobal: <%s>, NewVal: <%s>, Scope: <%s>, Command: <%s>\n"
503  let item     = remove(g:options, 0)
504  let expected = printf(template, item[0], item[1], item[2], item[3], item[4], item[5], item[6])
505  let actual   = printf(template, a:match, v:option_old, v:option_oldlocal, v:option_oldglobal, v:option_new, v:option_type, v:option_command)
506  let g:opt    = [expected, actual]
507  "call assert_equal(expected, actual)
508endfunc
509
510func Test_OptionSet()
511  if !has("eval") || !exists("+autochdir")
512    return
513  endif
514
515  badd test_autocmd.vim
516
517  call test_override('starting', 1)
518  set nocp
519  au OptionSet * :call s:AutoCommandOptionSet(expand("<amatch>"))
520
521  " 1: Setting number option"
522  let g:options=[['number', 0, 0, 0, 1, 'global', 'set']]
523  set nu
524  call assert_equal([], g:options)
525  call assert_equal(g:opt[0], g:opt[1])
526
527  " 2: Setting local number option"
528  let g:options=[['number', 1, 1, '', 0, 'local', 'setlocal']]
529  setlocal nonu
530  call assert_equal([], g:options)
531  call assert_equal(g:opt[0], g:opt[1])
532
533  " 3: Setting global number option"
534  let g:options=[['number', 1, '', 1, 0, 'global', 'setglobal']]
535  setglobal nonu
536  call assert_equal([], g:options)
537  call assert_equal(g:opt[0], g:opt[1])
538
539  " 4: Setting local autoindent option"
540  let g:options=[['autoindent', 0, 0, '', 1, 'local', 'setlocal']]
541  setlocal ai
542  call assert_equal([], g:options)
543  call assert_equal(g:opt[0], g:opt[1])
544
545  " 5: Setting global autoindent option"
546  let g:options=[['autoindent', 0, '', 0, 1, 'global', 'setglobal']]
547  setglobal ai
548  call assert_equal([], g:options)
549  call assert_equal(g:opt[0], g:opt[1])
550
551  " 6: Setting global autoindent option"
552  let g:options=[['autoindent', 1, 1, 1, 0, 'global', 'set']]
553  set ai!
554  call assert_equal([], g:options)
555  call assert_equal(g:opt[0], g:opt[1])
556
557  " 6a: Setting global autoindent option"
558  let g:options=[['autoindent', 1, 1, 0, 0, 'global', 'set']]
559  noa setlocal ai
560  noa setglobal noai
561  set ai!
562  call assert_equal([], g:options)
563  call assert_equal(g:opt[0], g:opt[1])
564
565  " Should not print anything, use :noa
566  " 7: don't trigger OptionSet"
567  let g:options=[['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid']]
568  noa set nonu
569  call assert_equal([['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid']], g:options)
570  call assert_equal(g:opt[0], g:opt[1])
571
572  " 8: Setting several global list and number option"
573  let g:options=[['list', 0, 0, 0, 1, 'global', 'set'], ['number', 0, 0, 0, 1, 'global', 'set']]
574  set list nu
575  call assert_equal([], g:options)
576  call assert_equal(g:opt[0], g:opt[1])
577
578  " 9: don't trigger OptionSet"
579  let g:options=[['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid'], ['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid']]
580  noa set nolist nonu
581  call assert_equal([['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid'], ['invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid', 'invalid']], g:options)
582  call assert_equal(g:opt[0], g:opt[1])
583
584  " 10: Setting global acd"
585  let g:options=[['autochdir', 0, 0, '', 1, 'local', 'setlocal']]
586  setlocal acd
587  call assert_equal([], g:options)
588  call assert_equal(g:opt[0], g:opt[1])
589
590  " 11: Setting global autoread (also sets local value)"
591  let g:options=[['autoread', 0, 0, 0, 1, 'global', 'set']]
592  set ar
593  call assert_equal([], g:options)
594  call assert_equal(g:opt[0], g:opt[1])
595
596  " 12: Setting local autoread"
597  let g:options=[['autoread', 1, 1, '', 1, 'local', 'setlocal']]
598  setlocal ar
599  call assert_equal([], g:options)
600  call assert_equal(g:opt[0], g:opt[1])
601
602  " 13: Setting global autoread"
603  let g:options=[['autoread', 1, '', 1, 0, 'global', 'setglobal']]
604  setglobal invar
605  call assert_equal([], g:options)
606  call assert_equal(g:opt[0], g:opt[1])
607
608  " 14: Setting option backspace through :let"
609  let g:options=[['backspace', '', '', '', 'eol,indent,start', 'global', 'set']]
610  let &bs="eol,indent,start"
611  call assert_equal([], g:options)
612  call assert_equal(g:opt[0], g:opt[1])
613
614  " 15: Setting option backspace through setbufvar()"
615  let g:options=[['backup', 0, 0, '', 1, 'local', 'setlocal']]
616  " try twice, first time, shouldn't trigger because option name is invalid,
617  " second time, it should trigger
618  let bnum = bufnr('%')
619  call assert_fails("call setbufvar(bnum, '&l:bk', 1)", "E355")
620  " should trigger, use correct option name
621  call setbufvar(bnum, '&backup', 1)
622  call assert_equal([], g:options)
623  call assert_equal(g:opt[0], g:opt[1])
624
625  " 16: Setting number option using setwinvar"
626  let g:options=[['number', 0, 0, '', 1, 'local', 'setlocal']]
627  call setwinvar(0, '&number', 1)
628  call assert_equal([], g:options)
629  call assert_equal(g:opt[0], g:opt[1])
630
631  " 17: Setting key option, shouldn't trigger"
632  let g:options=[['key', 'invalid', 'invalid1', 'invalid2', 'invalid3', 'invalid4', 'invalid5']]
633  setlocal key=blah
634  setlocal key=
635  call assert_equal([['key', 'invalid', 'invalid1', 'invalid2', 'invalid3', 'invalid4', 'invalid5']], g:options)
636  call assert_equal(g:opt[0], g:opt[1])
637
638
639  " 18a: Setting string global option"
640  let oldval = &backupext
641  let g:options=[['backupext', oldval, oldval, oldval, 'foo', 'global', 'set']]
642  set backupext=foo
643  call assert_equal([], g:options)
644  call assert_equal(g:opt[0], g:opt[1])
645
646  " 18b: Resetting string global option"
647  let g:options=[['backupext', 'foo', 'foo', 'foo', oldval, 'global', 'set']]
648  set backupext&
649  call assert_equal([], g:options)
650  call assert_equal(g:opt[0], g:opt[1])
651
652  " 18c: Setting global string global option"
653  let g:options=[['backupext', oldval, '', oldval, 'bar', 'global', 'setglobal']]
654  setglobal backupext=bar
655  call assert_equal([], g:options)
656  call assert_equal(g:opt[0], g:opt[1])
657
658  " 18d: Setting local string global option"
659  " As this is a global option this sets the global value even though
660  " :setlocal is used!
661  noa set backupext& " Reset global and local value (without triggering autocmd)
662  let g:options=[['backupext', oldval, oldval, '', 'baz', 'local', 'setlocal']]
663  setlocal backupext=baz
664  call assert_equal([], g:options)
665  call assert_equal(g:opt[0], g:opt[1])
666
667  " 18e: Setting again string global option"
668  noa setglobal backupext=ext_global " Reset global and local value (without triggering autocmd)
669  noa setlocal backupext=ext_local " Sets the global(!) value!
670  let g:options=[['backupext', 'ext_local', 'ext_local', 'ext_local', 'fuu', 'global', 'set']]
671  set backupext=fuu
672  call assert_equal([], g:options)
673  call assert_equal(g:opt[0], g:opt[1])
674
675
676  " 19a: Setting string local-global (to buffer) option"
677  let oldval = &tags
678  let g:options=[['tags', oldval, oldval, oldval, 'tagpath', 'global', 'set']]
679  set tags=tagpath
680  call assert_equal([], g:options)
681  call assert_equal(g:opt[0], g:opt[1])
682
683  " 19b: Resetting string local-global (to buffer) option"
684  let g:options=[['tags', 'tagpath', 'tagpath', 'tagpath', oldval, 'global', 'set']]
685  set tags&
686  call assert_equal([], g:options)
687  call assert_equal(g:opt[0], g:opt[1])
688
689  " 19c: Setting global string local-global (to buffer) option "
690  let g:options=[['tags', oldval, '', oldval, 'tagpath1', 'global', 'setglobal']]
691  setglobal tags=tagpath1
692  call assert_equal([], g:options)
693  call assert_equal(g:opt[0], g:opt[1])
694
695  " 19d: Setting local string local-global (to buffer) option"
696  let g:options=[['tags', 'tagpath1', 'tagpath1', '', 'tagpath2', 'local', 'setlocal']]
697  setlocal tags=tagpath2
698  call assert_equal([], g:options)
699  call assert_equal(g:opt[0], g:opt[1])
700
701  " 19e: Setting again string local-global (to buffer) option"
702  " Note: v:option_old is the old global value for local-global string options
703  " but the old local value for all other kinds of options.
704  noa setglobal tags=tag_global " Reset global and local value (without triggering autocmd)
705  noa setlocal tags=tag_local
706  let g:options=[['tags', 'tag_global', 'tag_local', 'tag_global', 'tagpath', 'global', 'set']]
707  set tags=tagpath
708  call assert_equal([], g:options)
709  call assert_equal(g:opt[0], g:opt[1])
710
711  " 19f: Setting string local-global (to buffer) option to an empty string"
712  " Note: v:option_old is the old global value for local-global string options
713  " but the old local value for all other kinds of options.
714  noa set tags=tag_global " Reset global and local value (without triggering autocmd)
715  noa setlocal tags= " empty string
716  let g:options=[['tags', 'tag_global', '', 'tag_global', 'tagpath', 'global', 'set']]
717  set tags=tagpath
718  call assert_equal([], g:options)
719  call assert_equal(g:opt[0], g:opt[1])
720
721
722  " 20a: Setting string local (to buffer) option"
723  let oldval = &spelllang
724  let g:options=[['spelllang', oldval, oldval, oldval, 'elvish,klingon', 'global', 'set']]
725  set spelllang=elvish,klingon
726  call assert_equal([], g:options)
727  call assert_equal(g:opt[0], g:opt[1])
728
729  " 20b: Resetting string local (to buffer) option"
730  let g:options=[['spelllang', 'elvish,klingon', 'elvish,klingon', 'elvish,klingon', oldval, 'global', 'set']]
731  set spelllang&
732  call assert_equal([], g:options)
733  call assert_equal(g:opt[0], g:opt[1])
734
735  " 20c: Setting global string local (to buffer) option"
736  let g:options=[['spelllang', oldval, '', oldval, 'elvish', 'global', 'setglobal']]
737  setglobal spelllang=elvish
738  call assert_equal([], g:options)
739  call assert_equal(g:opt[0], g:opt[1])
740
741  " 20d: Setting local string local (to buffer) option"
742  noa set spelllang& " Reset global and local value (without triggering autocmd)
743  let g:options=[['spelllang', oldval, oldval, '', 'klingon', 'local', 'setlocal']]
744  setlocal spelllang=klingon
745  call assert_equal([], g:options)
746  call assert_equal(g:opt[0], g:opt[1])
747
748  " 20e: Setting again string local (to buffer) option"
749  " Note: v:option_old is the old global value for local-global string options
750  " but the old local value for all other kinds of options.
751  noa setglobal spelllang=spellglobal " Reset global and local value (without triggering autocmd)
752  noa setlocal spelllang=spelllocal
753  let g:options=[['spelllang', 'spelllocal', 'spelllocal', 'spellglobal', 'foo', 'global', 'set']]
754  set spelllang=foo
755  call assert_equal([], g:options)
756  call assert_equal(g:opt[0], g:opt[1])
757
758
759  " 21a: Setting string local-global (to window) option"
760  let oldval = &statusline
761  let g:options=[['statusline', oldval, oldval, oldval, 'foo', 'global', 'set']]
762  set statusline=foo
763  call assert_equal([], g:options)
764  call assert_equal(g:opt[0], g:opt[1])
765
766  " 21b: Resetting string local-global (to window) option"
767  " Note: v:option_old is the old global value for local-global string options
768  " but the old local value for all other kinds of options.
769  let g:options=[['statusline', 'foo', 'foo', 'foo', oldval, 'global', 'set']]
770  set statusline&
771  call assert_equal([], g:options)
772  call assert_equal(g:opt[0], g:opt[1])
773
774  " 21c: Setting global string local-global (to window) option"
775  let g:options=[['statusline', oldval, '', oldval, 'bar', 'global', 'setglobal']]
776  setglobal statusline=bar
777  call assert_equal([], g:options)
778  call assert_equal(g:opt[0], g:opt[1])
779
780  " 21d: Setting local string local-global (to window) option"
781  noa set statusline& " Reset global and local value (without triggering autocmd)
782  let g:options=[['statusline', oldval, oldval, '', 'baz', 'local', 'setlocal']]
783  setlocal statusline=baz
784  call assert_equal([], g:options)
785  call assert_equal(g:opt[0], g:opt[1])
786
787  " 21e: Setting again string local-global (to window) option"
788  " Note: v:option_old is the old global value for local-global string options
789  " but the old local value for all other kinds of options.
790  noa setglobal statusline=bar " Reset global and local value (without triggering autocmd)
791  noa setlocal statusline=baz
792  let g:options=[['statusline', 'bar', 'baz', 'bar', 'foo', 'global', 'set']]
793  set statusline=foo
794  call assert_equal([], g:options)
795  call assert_equal(g:opt[0], g:opt[1])
796
797
798  " 22a: Setting string local (to window) option"
799  let oldval = &foldignore
800  let g:options=[['foldignore', oldval, oldval, oldval, 'fo', 'global', 'set']]
801  set foldignore=fo
802  call assert_equal([], g:options)
803  call assert_equal(g:opt[0], g:opt[1])
804
805  " 22b: Resetting string local (to window) option"
806  let g:options=[['foldignore', 'fo', 'fo', 'fo', oldval, 'global', 'set']]
807  set foldignore&
808  call assert_equal([], g:options)
809  call assert_equal(g:opt[0], g:opt[1])
810
811  " 22c: Setting global string local (to window) option"
812  let g:options=[['foldignore', oldval, '', oldval, 'bar', 'global', 'setglobal']]
813  setglobal foldignore=bar
814  call assert_equal([], g:options)
815  call assert_equal(g:opt[0], g:opt[1])
816
817  " 22d: Setting local string local (to window) option"
818  noa set foldignore& " Reset global and local value (without triggering autocmd)
819  let g:options=[['foldignore', oldval, oldval, '', 'baz', 'local', 'setlocal']]
820  setlocal foldignore=baz
821  call assert_equal([], g:options)
822  call assert_equal(g:opt[0], g:opt[1])
823
824  " 22e: Setting again string local (to window) option"
825  noa setglobal foldignore=glob " Reset global and local value (without triggering autocmd)
826  noa setlocal foldignore=loc
827  let g:options=[['foldignore', 'loc', 'loc', 'glob', 'fo', 'global', 'set']]
828  set foldignore=fo
829  call assert_equal([], g:options)
830  call assert_equal(g:opt[0], g:opt[1])
831
832
833  " 23a: Setting global number local option"
834  noa setglobal cmdheight=8 " Reset global and local value (without triggering autocmd)
835  noa setlocal cmdheight=1 " Sets the global(!) value!
836  let g:options=[['cmdheight', '1', '', '1', '2', 'global', 'setglobal']]
837  setglobal cmdheight=2
838  call assert_equal([], g:options)
839  call assert_equal(g:opt[0], g:opt[1])
840
841  " 23b: Setting local number global option"
842  noa setglobal cmdheight=8 " Reset global and local value (without triggering autocmd)
843  noa setlocal cmdheight=1 " Sets the global(!) value!
844  let g:options=[['cmdheight', '1', '1', '', '2', 'local', 'setlocal']]
845  setlocal cmdheight=2
846  call assert_equal([], g:options)
847  call assert_equal(g:opt[0], g:opt[1])
848
849  " 23c: Setting again number global option"
850  noa setglobal cmdheight=8 " Reset global and local value (without triggering autocmd)
851  noa setlocal cmdheight=1 " Sets the global(!) value!
852  let g:options=[['cmdheight', '1', '1', '1', '2', 'global', 'set']]
853  set cmdheight=2
854  call assert_equal([], g:options)
855  call assert_equal(g:opt[0], g:opt[1])
856
857  " 23d: Setting again number global option"
858  noa set cmdheight=8 " Reset global and local value (without triggering autocmd)
859  let g:options=[['cmdheight', '8', '8', '8', '2', 'global', 'set']]
860  set cmdheight=2
861  call assert_equal([], g:options)
862  call assert_equal(g:opt[0], g:opt[1])
863
864
865  " 24a: Setting global number global-local (to buffer) option"
866  noa setglobal undolevels=8 " Reset global and local value (without triggering autocmd)
867  noa setlocal undolevels=1
868  let g:options=[['undolevels', '8', '', '8', '2', 'global', 'setglobal']]
869  setglobal undolevels=2
870  call assert_equal([], g:options)
871  call assert_equal(g:opt[0], g:opt[1])
872
873  " 24b: Setting local number global-local (to buffer) option"
874  noa setglobal undolevels=8 " Reset global and local value (without triggering autocmd)
875  noa setlocal undolevels=1
876  let g:options=[['undolevels', '1', '1', '', '2', 'local', 'setlocal']]
877  setlocal undolevels=2
878  call assert_equal([], g:options)
879  call assert_equal(g:opt[0], g:opt[1])
880
881  " 24c: Setting again number global-local (to buffer) option"
882  noa setglobal undolevels=8 " Reset global and local value (without triggering autocmd)
883  noa setlocal undolevels=1
884  let g:options=[['undolevels', '1', '1', '8', '2', 'global', 'set']]
885  set undolevels=2
886  call assert_equal([], g:options)
887  call assert_equal(g:opt[0], g:opt[1])
888
889  " 24d: Setting again global number global-local (to buffer) option"
890  noa set undolevels=8 " Reset global and local value (without triggering autocmd)
891  let g:options=[['undolevels', '8', '8', '8', '2', 'global', 'set']]
892  set undolevels=2
893  call assert_equal([], g:options)
894  call assert_equal(g:opt[0], g:opt[1])
895
896
897  " 25a: Setting global number local (to buffer) option"
898  noa setglobal wrapmargin=8 " Reset global and local value (without triggering autocmd)
899  noa setlocal wrapmargin=1
900  let g:options=[['wrapmargin', '8', '', '8', '2', 'global', 'setglobal']]
901  setglobal wrapmargin=2
902  call assert_equal([], g:options)
903  call assert_equal(g:opt[0], g:opt[1])
904
905  " 25b: Setting local number local (to buffer) option"
906  noa setglobal wrapmargin=8 " Reset global and local value (without triggering autocmd)
907  noa setlocal wrapmargin=1
908  let g:options=[['wrapmargin', '1', '1', '', '2', 'local', 'setlocal']]
909  setlocal wrapmargin=2
910  call assert_equal([], g:options)
911  call assert_equal(g:opt[0], g:opt[1])
912
913  " 25c: Setting again number local (to buffer) option"
914  noa setglobal wrapmargin=8 " Reset global and local value (without triggering autocmd)
915  noa setlocal wrapmargin=1
916  let g:options=[['wrapmargin', '1', '1', '8', '2', 'global', 'set']]
917  set wrapmargin=2
918  call assert_equal([], g:options)
919  call assert_equal(g:opt[0], g:opt[1])
920
921  " 25d: Setting again global number local (to buffer) option"
922  noa set wrapmargin=8 " Reset global and local value (without triggering autocmd)
923  let g:options=[['wrapmargin', '8', '8', '8', '2', 'global', 'set']]
924  set wrapmargin=2
925  call assert_equal([], g:options)
926  call assert_equal(g:opt[0], g:opt[1])
927
928
929  " 26: Setting number global-local (to window) option.
930  " Such option does currently not exist.
931
932
933  " 27a: Setting global number local (to window) option"
934  noa setglobal foldcolumn=8 " Reset global and local value (without triggering autocmd)
935  noa setlocal foldcolumn=1
936  let g:options=[['foldcolumn', '8', '', '8', '2', 'global', 'setglobal']]
937  setglobal foldcolumn=2
938  call assert_equal([], g:options)
939  call assert_equal(g:opt[0], g:opt[1])
940
941  " 27b: Setting local number local (to window) option"
942  noa setglobal foldcolumn=8 " Reset global and local value (without triggering autocmd)
943  noa setlocal foldcolumn=1
944  let g:options=[['foldcolumn', '1', '1', '', '2', 'local', 'setlocal']]
945  setlocal foldcolumn=2
946  call assert_equal([], g:options)
947  call assert_equal(g:opt[0], g:opt[1])
948
949  " 27c: Setting again number local (to window) option"
950  noa setglobal foldcolumn=8 " Reset global and local value (without triggering autocmd)
951  noa setlocal foldcolumn=1
952  let g:options=[['foldcolumn', '1', '1', '8', '2', 'global', 'set']]
953  set foldcolumn=2
954  call assert_equal([], g:options)
955  call assert_equal(g:opt[0], g:opt[1])
956
957  " 27d: Ssettin again global number local (to window) option"
958  noa set foldcolumn=8 " Reset global and local value (without triggering autocmd)
959  let g:options=[['foldcolumn', '8', '8', '8', '2', 'global', 'set']]
960  set foldcolumn=2
961  call assert_equal([], g:options)
962  call assert_equal(g:opt[0], g:opt[1])
963
964
965  " 28a: Setting global boolean global option"
966  noa setglobal nowrapscan " Reset global and local value (without triggering autocmd)
967  noa setlocal wrapscan " Sets the global(!) value!
968  let g:options=[['wrapscan', '1', '', '1', '0', 'global', 'setglobal']]
969  setglobal nowrapscan
970  call assert_equal([], g:options)
971  call assert_equal(g:opt[0], g:opt[1])
972
973  " 28b: Setting local boolean global option"
974  noa setglobal nowrapscan " Reset global and local value (without triggering autocmd)
975  noa setlocal wrapscan " Sets the global(!) value!
976  let g:options=[['wrapscan', '1', '1', '', '0', 'local', 'setlocal']]
977  setlocal nowrapscan
978  call assert_equal([], g:options)
979  call assert_equal(g:opt[0], g:opt[1])
980
981  " 28c: Setting again boolean global option"
982  noa setglobal nowrapscan " Reset global and local value (without triggering autocmd)
983  noa setlocal wrapscan " Sets the global(!) value!
984  let g:options=[['wrapscan', '1', '1', '1', '0', 'global', 'set']]
985  set nowrapscan
986  call assert_equal([], g:options)
987  call assert_equal(g:opt[0], g:opt[1])
988
989  " 28d: Setting again global boolean global option"
990  noa set nowrapscan " Reset global and local value (without triggering autocmd)
991  let g:options=[['wrapscan', '0', '0', '0', '1', 'global', 'set']]
992  set wrapscan
993  call assert_equal([], g:options)
994  call assert_equal(g:opt[0], g:opt[1])
995
996
997  " 29a: Setting global boolean global-local (to buffer) option"
998  noa setglobal noautoread " Reset global and local value (without triggering autocmd)
999  noa setlocal autoread
1000  let g:options=[['autoread', '0', '', '0', '1', 'global', 'setglobal']]
1001  setglobal autoread
1002  call assert_equal([], g:options)
1003  call assert_equal(g:opt[0], g:opt[1])
1004
1005  " 29b: Setting local boolean global-local (to buffer) option"
1006  noa setglobal noautoread " Reset global and local value (without triggering autocmd)
1007  noa setlocal autoread
1008  let g:options=[['autoread', '1', '1', '', '0', 'local', 'setlocal']]
1009  setlocal noautoread
1010  call assert_equal([], g:options)
1011  call assert_equal(g:opt[0], g:opt[1])
1012
1013  " 29c: Setting again boolean global-local (to buffer) option"
1014  noa setglobal noautoread " Reset global and local value (without triggering autocmd)
1015  noa setlocal autoread
1016  let g:options=[['autoread', '1', '1', '0', '1', 'global', 'set']]
1017  set autoread
1018  call assert_equal([], g:options)
1019  call assert_equal(g:opt[0], g:opt[1])
1020
1021  " 29d: Setting again global boolean global-local (to buffer) option"
1022  noa set noautoread " Reset global and local value (without triggering autocmd)
1023  let g:options=[['autoread', '0', '0', '0', '1', 'global', 'set']]
1024  set autoread
1025  call assert_equal([], g:options)
1026  call assert_equal(g:opt[0], g:opt[1])
1027
1028
1029  " 30a: Setting global boolean local (to buffer) option"
1030  noa setglobal nocindent " Reset global and local value (without triggering autocmd)
1031  noa setlocal cindent
1032  let g:options=[['cindent', '0', '', '0', '1', 'global', 'setglobal']]
1033  setglobal cindent
1034  call assert_equal([], g:options)
1035  call assert_equal(g:opt[0], g:opt[1])
1036
1037  " 30b: Setting local boolean local (to buffer) option"
1038  noa setglobal nocindent " Reset global and local value (without triggering autocmd)
1039  noa setlocal cindent
1040  let g:options=[['cindent', '1', '1', '', '0', 'local', 'setlocal']]
1041  setlocal nocindent
1042  call assert_equal([], g:options)
1043  call assert_equal(g:opt[0], g:opt[1])
1044
1045  " 30c: Setting again boolean local (to buffer) option"
1046  noa setglobal nocindent " Reset global and local value (without triggering autocmd)
1047  noa setlocal cindent
1048  let g:options=[['cindent', '1', '1', '0', '1', 'global', 'set']]
1049  set cindent
1050  call assert_equal([], g:options)
1051  call assert_equal(g:opt[0], g:opt[1])
1052
1053  " 30d: Setting again global boolean local (to buffer) option"
1054  noa set nocindent " Reset global and local value (without triggering autocmd)
1055  let g:options=[['cindent', '0', '0', '0', '1', 'global', 'set']]
1056  set cindent
1057  call assert_equal([], g:options)
1058  call assert_equal(g:opt[0], g:opt[1])
1059
1060
1061  " 31: Setting boolean global-local (to window) option
1062  " Currently no such option exists.
1063
1064
1065  " 32a: Setting global boolean local (to window) option"
1066  noa setglobal nocursorcolumn " Reset global and local value (without triggering autocmd)
1067  noa setlocal cursorcolumn
1068  let g:options=[['cursorcolumn', '0', '', '0', '1', 'global', 'setglobal']]
1069  setglobal cursorcolumn
1070  call assert_equal([], g:options)
1071  call assert_equal(g:opt[0], g:opt[1])
1072
1073  " 32b: Setting local boolean local (to window) option"
1074  noa setglobal nocursorcolumn " Reset global and local value (without triggering autocmd)
1075  noa setlocal cursorcolumn
1076  let g:options=[['cursorcolumn', '1', '1', '', '0', 'local', 'setlocal']]
1077  setlocal nocursorcolumn
1078  call assert_equal([], g:options)
1079  call assert_equal(g:opt[0], g:opt[1])
1080
1081  " 32c: Setting again boolean local (to window) option"
1082  noa setglobal nocursorcolumn " Reset global and local value (without triggering autocmd)
1083  noa setlocal cursorcolumn
1084  let g:options=[['cursorcolumn', '1', '1', '0', '1', 'global', 'set']]
1085  set cursorcolumn
1086  call assert_equal([], g:options)
1087  call assert_equal(g:opt[0], g:opt[1])
1088
1089  " 32d: Setting again global boolean local (to window) option"
1090  noa set nocursorcolumn " Reset global and local value (without triggering autocmd)
1091  let g:options=[['cursorcolumn', '0', '0', '0', '1', 'global', 'set']]
1092  set cursorcolumn
1093  call assert_equal([], g:options)
1094  call assert_equal(g:opt[0], g:opt[1])
1095
1096
1097  " 33: Test autocommands when an option value is converted internally.
1098  noa set backspace=1 " Reset global and local value (without triggering autocmd)
1099  let g:options=[['backspace', 'indent,eol', 'indent,eol', 'indent,eol', '2', 'global', 'set']]
1100  set backspace=2
1101  call assert_equal([], g:options)
1102  call assert_equal(g:opt[0], g:opt[1])
1103
1104
1105  " Cleanup
1106  au! OptionSet
1107  " set tags&
1108  for opt in ['nu', 'ai', 'acd', 'ar', 'bs', 'backup', 'cul', 'cp', 'backupext', 'tags', 'spelllang', 'statusline', 'foldignore', 'cmdheight', 'undolevels', 'wrapmargin', 'foldcolumn', 'wrapscan', 'autoread', 'cindent', 'cursorcolumn']
1109    exe printf(":set %s&vim", opt)
1110  endfor
1111  call test_override('starting', 0)
1112  delfunc! AutoCommandOptionSet
1113endfunc
1114
1115func Test_OptionSet_diffmode()
1116  call test_override('starting', 1)
1117  " 18: Changing an option when entering diff mode
1118  new
1119  au OptionSet diff :let &l:cul=v:option_new
1120
1121  call setline(1, ['buffer 1', 'line2', 'line3', 'line4'])
1122  call assert_equal(0, &l:cul)
1123  diffthis
1124  call assert_equal(1, &l:cul)
1125
1126  vnew
1127  call setline(1, ['buffer 2', 'line 2', 'line 3', 'line4'])
1128  call assert_equal(0, &l:cul)
1129  diffthis
1130  call assert_equal(1, &l:cul)
1131
1132  diffoff
1133  call assert_equal(0, &l:cul)
1134  call assert_equal(1, getwinvar(2, '&l:cul'))
1135  bw!
1136
1137  call assert_equal(1, &l:cul)
1138  diffoff!
1139  call assert_equal(0, &l:cul)
1140  call assert_equal(0, getwinvar(1, '&l:cul'))
1141  bw!
1142
1143  " Cleanup
1144  au! OptionSet
1145  call test_override('starting', 0)
1146endfunc
1147
1148func Test_OptionSet_diffmode_close()
1149  call test_override('starting', 1)
1150  " 19: Try to close the current window when entering diff mode
1151  " should not segfault
1152  new
1153  au OptionSet diff close
1154
1155  call setline(1, ['buffer 1', 'line2', 'line3', 'line4'])
1156  call assert_fails(':diffthis', 'E788')
1157  call assert_equal(1, &diff)
1158  vnew
1159  call setline(1, ['buffer 2', 'line 2', 'line 3', 'line4'])
1160  call assert_fails(':diffthis', 'E788')
1161  call assert_equal(1, &diff)
1162  set diffopt-=closeoff
1163  bw!
1164  call assert_fails(':diffoff!', 'E788')
1165  bw!
1166
1167  " Cleanup
1168  au! OptionSet
1169  call test_override('starting', 0)
1170  "delfunc! AutoCommandOptionSet
1171endfunc
1172
1173" Test for Bufleave autocommand that deletes the buffer we are about to edit.
1174func Test_BufleaveWithDelete()
1175  new | edit Xfile1
1176
1177  augroup test_bufleavewithdelete
1178      autocmd!
1179      autocmd BufLeave Xfile1 bwipe Xfile2
1180  augroup END
1181
1182  call assert_fails('edit Xfile2', 'E143:')
1183  call assert_equal('Xfile1', bufname('%'))
1184
1185  autocmd! test_bufleavewithdelete BufLeave Xfile1
1186  augroup! test_bufleavewithdelete
1187
1188  new
1189  bwipe! Xfile1
1190endfunc
1191
1192" Test for autocommand that changes the buffer list, when doing ":ball".
1193func Test_Acmd_BufAll()
1194  enew!
1195  %bwipe!
1196  call writefile(['Test file Xxx1'], 'Xxx1')
1197  call writefile(['Test file Xxx2'], 'Xxx2')
1198  call writefile(['Test file Xxx3'], 'Xxx3')
1199
1200  " Add three files to the buffer list
1201  split Xxx1
1202  close
1203  split Xxx2
1204  close
1205  split Xxx3
1206  close
1207
1208  " Wipe the buffer when the buffer is opened
1209  au BufReadPost Xxx2 bwipe
1210
1211  call append(0, 'Test file Xxx4')
1212  ball
1213
1214  call assert_equal(2, winnr('$'))
1215  call assert_equal('Xxx1', bufname(winbufnr(winnr('$'))))
1216  wincmd t
1217
1218  au! BufReadPost
1219  %bwipe!
1220  call delete('Xxx1')
1221  call delete('Xxx2')
1222  call delete('Xxx3')
1223  enew! | only
1224endfunc
1225
1226" Test for autocommand that changes current buffer on BufEnter event.
1227" Check if modelines are interpreted for the correct buffer.
1228func Test_Acmd_BufEnter()
1229  %bwipe!
1230  call writefile(['start of test file Xxx1',
1231	      \ "\<Tab>this is a test",
1232	      \ 'end of test file Xxx1'], 'Xxx1')
1233  call writefile(['start of test file Xxx2',
1234	      \ 'vim: set noai :',
1235	      \ "\<Tab>this is a test",
1236	      \ 'end of test file Xxx2'], 'Xxx2')
1237
1238  au BufEnter Xxx2 brew
1239  set ai modeline modelines=3
1240  edit Xxx1
1241  " edit Xxx2, autocmd will do :brew
1242  edit Xxx2
1243  exe "normal G?this is a\<CR>"
1244  " Append text with autoindent to this file
1245  normal othis should be auto-indented
1246  call assert_equal("\<Tab>this should be auto-indented", getline('.'))
1247  call assert_equal(3, line('.'))
1248  " Remove autocmd and edit Xxx2 again
1249  au! BufEnter Xxx2
1250  buf! Xxx2
1251  exe "normal G?this is a\<CR>"
1252  " append text without autoindent to Xxx
1253  normal othis should be in column 1
1254  call assert_equal("this should be in column 1", getline('.'))
1255  call assert_equal(4, line('.'))
1256
1257  %bwipe!
1258  call delete('Xxx1')
1259  call delete('Xxx2')
1260  set ai&vim modeline&vim modelines&vim
1261endfunc
1262
1263" Test for issue #57
1264" do not move cursor on <c-o> when autoindent is set
1265func Test_ai_CTRL_O()
1266  enew!
1267  set ai
1268  let save_fo = &fo
1269  set fo+=r
1270  exe "normal o# abcdef\<Esc>2hi\<CR>\<C-O>d0\<Esc>"
1271  exe "normal o# abcdef\<Esc>2hi\<C-O>d0\<Esc>"
1272  call assert_equal(['# abc', 'def', 'def'], getline(2, 4))
1273
1274  set ai&vim
1275  let &fo = save_fo
1276  enew!
1277endfunc
1278
1279" Test for autocommand that deletes the current buffer on BufLeave event.
1280" Also test deleting the last buffer, should give a new, empty buffer.
1281func Test_BufLeave_Wipe()
1282  %bwipe!
1283  let content = ['start of test file Xxx',
1284	      \ 'this is a test',
1285	      \ 'end of test file Xxx']
1286  call writefile(content, 'Xxx1')
1287  call writefile(content, 'Xxx2')
1288
1289  au BufLeave Xxx2 bwipe
1290  edit Xxx1
1291  split Xxx2
1292  " delete buffer Xxx2, we should be back to Xxx1
1293  bwipe
1294  call assert_equal('Xxx1', bufname('%'))
1295  call assert_equal(1, winnr('$'))
1296
1297  " Create an alternate buffer
1298  %write! test.out
1299  call assert_equal('test.out', bufname('#'))
1300  " delete alternate buffer
1301  bwipe test.out
1302  call assert_equal('Xxx1', bufname('%'))
1303  call assert_equal('', bufname('#'))
1304
1305  au BufLeave Xxx1 bwipe
1306  " delete current buffer, get an empty one
1307  bwipe!
1308  call assert_equal(1, line('$'))
1309  call assert_equal('', bufname('%'))
1310  let g:bufinfo = getbufinfo()
1311  call assert_equal(1, len(g:bufinfo))
1312
1313  call delete('Xxx1')
1314  call delete('Xxx2')
1315  call delete('test.out')
1316  %bwipe
1317  au! BufLeave
1318
1319  " check that bufinfo doesn't contain a pointer to freed memory
1320  call test_garbagecollect_now()
1321endfunc
1322
1323func Test_QuitPre()
1324  edit Xfoo
1325  let winid = win_getid(winnr())
1326  split Xbar
1327  au! QuitPre * let g:afile = expand('<afile>')
1328  " Close the other window, <afile> should be correct.
1329  exe win_id2win(winid) . 'q'
1330  call assert_equal('Xfoo', g:afile)
1331
1332  unlet g:afile
1333  bwipe Xfoo
1334  bwipe Xbar
1335endfunc
1336
1337func Test_Cmdline()
1338  au! CmdlineChanged : let g:text = getcmdline()
1339  let g:text = 0
1340  call feedkeys(":echom 'hello'\<CR>", 'xt')
1341  call assert_equal("echom 'hello'", g:text)
1342  au! CmdlineChanged
1343
1344  au! CmdlineChanged : let g:entered = expand('<afile>')
1345  let g:entered = 0
1346  call feedkeys(":echom 'hello'\<CR>", 'xt')
1347  call assert_equal(':', g:entered)
1348  au! CmdlineChanged
1349
1350  au! CmdlineEnter : let g:entered = expand('<afile>')
1351  au! CmdlineLeave : let g:left = expand('<afile>')
1352  let g:entered = 0
1353  let g:left = 0
1354  call feedkeys(":echo 'hello'\<CR>", 'xt')
1355  call assert_equal(':', g:entered)
1356  call assert_equal(':', g:left)
1357  au! CmdlineEnter
1358  au! CmdlineLeave
1359
1360  let save_shellslash = &shellslash
1361  set noshellslash
1362  au! CmdlineEnter / let g:entered = expand('<afile>')
1363  au! CmdlineLeave / let g:left = expand('<afile>')
1364  let g:entered = 0
1365  let g:left = 0
1366  new
1367  call setline(1, 'hello')
1368  call feedkeys("/hello\<CR>", 'xt')
1369  call assert_equal('/', g:entered)
1370  call assert_equal('/', g:left)
1371  bwipe!
1372  au! CmdlineEnter
1373  au! CmdlineLeave
1374  let &shellslash = save_shellslash
1375endfunc
1376
1377" Test for BufWritePre autocommand that deletes or unloads the buffer.
1378func Test_BufWritePre()
1379  %bwipe
1380  au BufWritePre Xxx1 bunload
1381  au BufWritePre Xxx2 bwipe
1382
1383  call writefile(['start of Xxx1', 'test', 'end of Xxx1'], 'Xxx1')
1384  call writefile(['start of Xxx2', 'test', 'end of Xxx2'], 'Xxx2')
1385
1386  edit Xtest
1387  e! Xxx2
1388  bdel Xtest
1389  e Xxx1
1390  " write it, will unload it and give an error msg
1391  call assert_fails('w', 'E203')
1392  call assert_equal('Xxx2', bufname('%'))
1393  edit Xtest
1394  e! Xxx2
1395  bwipe Xtest
1396  " write it, will delete the buffer and give an error msg
1397  call assert_fails('w', 'E203')
1398  call assert_equal('Xxx1', bufname('%'))
1399  au! BufWritePre
1400  call delete('Xxx1')
1401  call delete('Xxx2')
1402endfunc
1403
1404" Test for BufUnload autocommand that unloads all the other buffers
1405func Test_bufunload_all()
1406  call writefile(['Test file Xxx1'], 'Xxx1')"
1407  call writefile(['Test file Xxx2'], 'Xxx2')"
1408
1409  let content =<< trim [CODE]
1410    func UnloadAllBufs()
1411      let i = 1
1412      while i <= bufnr('$')
1413        if i != bufnr('%') && bufloaded(i)
1414          exe  i . 'bunload'
1415        endif
1416        let i += 1
1417      endwhile
1418    endfunc
1419    au BufUnload * call UnloadAllBufs()
1420    au VimLeave * call writefile(['Test Finished'], 'Xout')
1421    edit Xxx1
1422    split Xxx2
1423    q
1424  [CODE]
1425
1426  call writefile(content, 'Xtest')
1427
1428  call delete('Xout')
1429  call system(GetVimCommandClean() .. ' -N --not-a-term -S Xtest')
1430  call assert_true(filereadable('Xout'))
1431
1432  call delete('Xxx1')
1433  call delete('Xxx2')
1434  call delete('Xtest')
1435  call delete('Xout')
1436endfunc
1437
1438" Some tests for buffer-local autocommands
1439func Test_buflocal_autocmd()
1440  let g:bname = ''
1441  edit xx
1442  au BufLeave <buffer> let g:bname = expand("%")
1443  " here, autocommand for xx should trigger.
1444  " but autocommand shall not apply to buffer named <buffer>.
1445  edit somefile
1446  call assert_equal('xx', g:bname)
1447  let g:bname = ''
1448  " here, autocommand shall be auto-deleted
1449  bwipe xx
1450  " autocmd should not trigger
1451  edit xx
1452  call assert_equal('', g:bname)
1453  " autocmd should not trigger
1454  edit somefile
1455  call assert_equal('', g:bname)
1456  enew
1457  unlet g:bname
1458endfunc
1459
1460" Test for "*Cmd" autocommands
1461func Test_Cmd_Autocmds()
1462  call writefile(['start of Xxx', "\tabc2", 'end of Xxx'], 'Xxx')
1463
1464  enew!
1465  au BufReadCmd XtestA 0r Xxx|$del
1466  edit XtestA			" will read text of Xxd instead
1467  call assert_equal('start of Xxx', getline(1))
1468
1469  au BufWriteCmd XtestA call append(line("$"), "write")
1470  write				" will append a line to the file
1471  call assert_equal('write', getline('$'))
1472  call assert_fails('read XtestA', 'E484')	" should not read anything
1473  call assert_equal('write', getline(4))
1474
1475  " now we have:
1476  " 1	start of Xxx
1477  " 2		abc2
1478  " 3	end of Xxx
1479  " 4	write
1480
1481  au FileReadCmd XtestB '[r Xxx
1482  2r XtestB			" will read Xxx below line 2 instead
1483  call assert_equal('start of Xxx', getline(3))
1484
1485  " now we have:
1486  " 1	start of Xxx
1487  " 2		abc2
1488  " 3	start of Xxx
1489  " 4		abc2
1490  " 5	end of Xxx
1491  " 6	end of Xxx
1492  " 7	write
1493
1494  au FileWriteCmd XtestC '[,']copy $
1495  normal 4GA1
1496  4,5w XtestC			" will copy lines 4 and 5 to the end
1497  call assert_equal("\tabc21", getline(8))
1498  call assert_fails('r XtestC', 'E484')	" should not read anything
1499  call assert_equal("end of Xxx", getline(9))
1500
1501  " now we have:
1502  " 1	start of Xxx
1503  " 2		abc2
1504  " 3	start of Xxx
1505  " 4		abc21
1506  " 5	end of Xxx
1507  " 6	end of Xxx
1508  " 7	write
1509  " 8		abc21
1510  " 9	end of Xxx
1511
1512  let g:lines = []
1513  au FileAppendCmd XtestD call extend(g:lines, getline(line("'["), line("']")))
1514  w >>XtestD			" will add lines to 'lines'
1515  call assert_equal(9, len(g:lines))
1516  call assert_fails('$r XtestD', 'E484')	" should not read anything
1517  call assert_equal(9, line('$'))
1518  call assert_equal('end of Xxx', getline('$'))
1519
1520  au BufReadCmd XtestE 0r Xxx|$del
1521  sp XtestE			" split window with test.out
1522  call assert_equal('end of Xxx', getline(3))
1523
1524  let g:lines = []
1525  exe "normal 2Goasdf\<Esc>\<C-W>\<C-W>"
1526  au BufWriteCmd XtestE call extend(g:lines, getline(0, '$'))
1527  wall				" will write other window to 'lines'
1528  call assert_equal(4, len(g:lines), g:lines)
1529  call assert_equal('asdf', g:lines[2])
1530
1531  au! BufReadCmd
1532  au! BufWriteCmd
1533  au! FileReadCmd
1534  au! FileWriteCmd
1535  au! FileAppendCmd
1536  %bwipe!
1537  call delete('Xxx')
1538  enew!
1539endfunc
1540
1541func s:ReadFile()
1542  setl noswapfile nomodified
1543  let filename = resolve(expand("<afile>:p"))
1544  execute 'read' fnameescape(filename)
1545  1d_
1546  exe 'file' fnameescape(filename)
1547  setl buftype=acwrite
1548endfunc
1549
1550func s:WriteFile()
1551  let filename = resolve(expand("<afile>:p"))
1552  setl buftype=
1553  noautocmd execute 'write' fnameescape(filename)
1554  setl buftype=acwrite
1555  setl nomodified
1556endfunc
1557
1558func Test_BufReadCmd()
1559  autocmd BufReadCmd *.test call s:ReadFile()
1560  autocmd BufWriteCmd *.test call s:WriteFile()
1561
1562  call writefile(['one', 'two', 'three'], 'Xcmd.test')
1563  edit Xcmd.test
1564  call assert_match('Xcmd.test" line 1 of 3', execute('file'))
1565  normal! Gofour
1566  write
1567  call assert_equal(['one', 'two', 'three', 'four'], readfile('Xcmd.test'))
1568
1569  bwipe!
1570  call delete('Xcmd.test')
1571  au! BufReadCmd
1572  au! BufWriteCmd
1573endfunc
1574
1575func SetChangeMarks(start, end)
1576  exe a:start. 'mark ['
1577  exe a:end. 'mark ]'
1578endfunc
1579
1580" Verify the effects of autocmds on '[ and ']
1581func Test_change_mark_in_autocmds()
1582  edit! Xtest
1583  call feedkeys("ia\<CR>b\<CR>c\<CR>d\<C-g>u", 'xtn')
1584
1585  call SetChangeMarks(2, 3)
1586  write
1587  call assert_equal([1, 4], [line("'["), line("']")])
1588
1589  call SetChangeMarks(2, 3)
1590  au BufWritePre * call assert_equal([1, 4], [line("'["), line("']")])
1591  write
1592  au! BufWritePre
1593
1594  if executable('cat')
1595    write XtestFilter
1596    write >> XtestFilter
1597
1598    call SetChangeMarks(2, 3)
1599    " Marks are set to the entire range of the write
1600    au FilterWritePre * call assert_equal([1, 4], [line("'["), line("']")])
1601    " '[ is adjusted to just before the line that will receive the filtered
1602    " data
1603    au FilterReadPre * call assert_equal([4, 4], [line("'["), line("']")])
1604    " The filtered data is read into the buffer, and the source lines are
1605    " still present, so the range is after the source lines
1606    au FilterReadPost * call assert_equal([5, 12], [line("'["), line("']")])
1607    %!cat XtestFilter
1608    " After the filtered data is read, the original lines are deleted
1609    call assert_equal([1, 8], [line("'["), line("']")])
1610    au! FilterWritePre,FilterReadPre,FilterReadPost
1611    undo
1612
1613    call SetChangeMarks(1, 4)
1614    au FilterWritePre * call assert_equal([2, 3], [line("'["), line("']")])
1615    au FilterReadPre * call assert_equal([3, 3], [line("'["), line("']")])
1616    au FilterReadPost * call assert_equal([4, 11], [line("'["), line("']")])
1617    2,3!cat XtestFilter
1618    call assert_equal([2, 9], [line("'["), line("']")])
1619    au! FilterWritePre,FilterReadPre,FilterReadPost
1620    undo
1621
1622    call delete('XtestFilter')
1623  endif
1624
1625  call SetChangeMarks(1, 4)
1626  au FileWritePre * call assert_equal([2, 3], [line("'["), line("']")])
1627  2,3write Xtest2
1628  au! FileWritePre
1629
1630  call SetChangeMarks(2, 3)
1631  au FileAppendPre * call assert_equal([1, 4], [line("'["), line("']")])
1632  write >> Xtest2
1633  au! FileAppendPre
1634
1635  call SetChangeMarks(1, 4)
1636  au FileAppendPre * call assert_equal([2, 3], [line("'["), line("']")])
1637  2,3write >> Xtest2
1638  au! FileAppendPre
1639
1640  call SetChangeMarks(1, 1)
1641  au FileReadPre * call assert_equal([3, 1], [line("'["), line("']")])
1642  au FileReadPost * call assert_equal([4, 11], [line("'["), line("']")])
1643  3read Xtest2
1644  au! FileReadPre,FileReadPost
1645  undo
1646
1647  call SetChangeMarks(4, 4)
1648  " When the line is 0, it's adjusted to 1
1649  au FileReadPre * call assert_equal([1, 4], [line("'["), line("']")])
1650  au FileReadPost * call assert_equal([1, 8], [line("'["), line("']")])
1651  0read Xtest2
1652  au! FileReadPre,FileReadPost
1653  undo
1654
1655  call SetChangeMarks(4, 4)
1656  " When the line is 0, it's adjusted to 1
1657  au FileReadPre * call assert_equal([1, 4], [line("'["), line("']")])
1658  au FileReadPost * call assert_equal([2, 9], [line("'["), line("']")])
1659  1read Xtest2
1660  au! FileReadPre,FileReadPost
1661  undo
1662
1663  bwipe!
1664  call delete('Xtest')
1665  call delete('Xtest2')
1666endfunc
1667
1668func Test_Filter_noshelltemp()
1669  if !executable('cat')
1670    return
1671  endif
1672
1673  enew!
1674  call setline(1, ['a', 'b', 'c', 'd'])
1675
1676  let shelltemp = &shelltemp
1677  set shelltemp
1678
1679  let g:filter_au = 0
1680  au FilterWritePre * let g:filter_au += 1
1681  au FilterReadPre * let g:filter_au += 1
1682  au FilterReadPost * let g:filter_au += 1
1683  %!cat
1684  call assert_equal(3, g:filter_au)
1685
1686  if has('filterpipe')
1687    set noshelltemp
1688
1689    let g:filter_au = 0
1690    au FilterWritePre * let g:filter_au += 1
1691    au FilterReadPre * let g:filter_au += 1
1692    au FilterReadPost * let g:filter_au += 1
1693    %!cat
1694    call assert_equal(0, g:filter_au)
1695  endif
1696
1697  au! FilterWritePre,FilterReadPre,FilterReadPost
1698  let &shelltemp = shelltemp
1699  bwipe!
1700endfunc
1701
1702func Test_TextYankPost()
1703  enew!
1704  call setline(1, ['foo'])
1705
1706  let g:event = []
1707  au TextYankPost * let g:event = copy(v:event)
1708
1709  call assert_equal({}, v:event)
1710  call assert_fails('let v:event = {}', 'E46:')
1711  call assert_fails('let v:event.mykey = 0', 'E742:')
1712
1713  norm "ayiw
1714  call assert_equal(
1715    \{'regcontents': ['foo'], 'regname': 'a', 'operator': 'y', 'regtype': 'v'},
1716    \g:event)
1717  norm y_
1718  call assert_equal(
1719    \{'regcontents': ['foo'], 'regname': '',  'operator': 'y', 'regtype': 'V'},
1720    \g:event)
1721  call feedkeys("\<C-V>y", 'x')
1722  call assert_equal(
1723    \{'regcontents': ['f'], 'regname': '',  'operator': 'y', 'regtype': "\x161"},
1724    \g:event)
1725  norm "xciwbar
1726  call assert_equal(
1727    \{'regcontents': ['foo'], 'regname': 'x', 'operator': 'c', 'regtype': 'v'},
1728    \g:event)
1729  norm "bdiw
1730  call assert_equal(
1731    \{'regcontents': ['bar'], 'regname': 'b', 'operator': 'd', 'regtype': 'v'},
1732    \g:event)
1733
1734  call assert_equal({}, v:event)
1735
1736  au! TextYankPost
1737  unlet g:event
1738  bwipe!
1739endfunc
1740
1741func Test_nocatch_wipe_all_buffers()
1742  " Real nasty autocommand: wipe all buffers on any event.
1743  au * * bwipe *
1744  " Get E93 first?
1745  " call assert_fails('next x', 'E93:')
1746  call assert_fails('next x', 'E517:')
1747  bwipe
1748  au!
1749endfunc
1750
1751func Test_nocatch_wipe_dummy_buffer()
1752  if has('quickfix')
1753    " Nasty autocommand: wipe buffer on any event.
1754    au * x bwipe
1755    call assert_fails('lv½ /x', 'E480')
1756    au!
1757  endif
1758endfunc
1759
1760function s:Before_test_dirchanged()
1761  augroup test_dirchanged
1762    autocmd!
1763  augroup END
1764  let s:li = []
1765  let s:dir_this = getcwd()
1766  let s:dir_foo = s:dir_this . '/Xfoo'
1767  call mkdir(s:dir_foo)
1768  let s:dir_bar = s:dir_this . '/Xbar'
1769  call mkdir(s:dir_bar)
1770endfunc
1771
1772function s:After_test_dirchanged()
1773  call chdir(s:dir_this)
1774  call delete(s:dir_foo, 'd')
1775  call delete(s:dir_bar, 'd')
1776  augroup test_dirchanged
1777    autocmd!
1778  augroup END
1779endfunc
1780
1781function Test_dirchanged_global()
1782  call s:Before_test_dirchanged()
1783  autocmd test_dirchanged DirChanged global call add(s:li, "cd:")
1784  autocmd test_dirchanged DirChanged global call add(s:li, expand("<afile>"))
1785  call chdir(s:dir_foo)
1786  call assert_equal(["cd:", s:dir_foo], s:li)
1787  call chdir(s:dir_foo)
1788  call assert_equal(["cd:", s:dir_foo], s:li)
1789  exe 'lcd ' .. fnameescape(s:dir_bar)
1790  call assert_equal(["cd:", s:dir_foo], s:li)
1791  call s:After_test_dirchanged()
1792endfunc
1793
1794function Test_dirchanged_local()
1795  call s:Before_test_dirchanged()
1796  autocmd test_dirchanged DirChanged window call add(s:li, "lcd:")
1797  autocmd test_dirchanged DirChanged window call add(s:li, expand("<afile>"))
1798  call chdir(s:dir_foo)
1799  call assert_equal([], s:li)
1800  exe 'lcd ' .. fnameescape(s:dir_bar)
1801  call assert_equal(["lcd:", s:dir_bar], s:li)
1802  exe 'lcd ' .. fnameescape(s:dir_bar)
1803  call assert_equal(["lcd:", s:dir_bar], s:li)
1804  call s:After_test_dirchanged()
1805endfunc
1806
1807function Test_dirchanged_auto()
1808  if !exists('+autochdir')
1809    return
1810  endif
1811  call s:Before_test_dirchanged()
1812  call test_autochdir()
1813  autocmd test_dirchanged DirChanged auto call add(s:li, "auto:")
1814  autocmd test_dirchanged DirChanged auto call add(s:li, expand("<afile>"))
1815  set acd
1816  cd ..
1817  call assert_equal([], s:li)
1818  exe 'edit ' . s:dir_foo . '/Xfile'
1819  call assert_equal(s:dir_foo, getcwd())
1820  call assert_equal(["auto:", s:dir_foo], s:li)
1821  set noacd
1822  bwipe!
1823  call s:After_test_dirchanged()
1824endfunc
1825
1826" Test TextChangedI and TextChangedP
1827func Test_ChangedP()
1828  new
1829  call setline(1, ['foo', 'bar', 'foobar'])
1830  call test_override("char_avail", 1)
1831  set complete=. completeopt=menuone
1832
1833  func! TextChangedAutocmd(char)
1834    let g:autocmd .= a:char
1835  endfunc
1836
1837  au! TextChanged <buffer> :call TextChangedAutocmd('N')
1838  au! TextChangedI <buffer> :call TextChangedAutocmd('I')
1839  au! TextChangedP <buffer> :call TextChangedAutocmd('P')
1840
1841  call cursor(3, 1)
1842  let g:autocmd = ''
1843  call feedkeys("o\<esc>", 'tnix')
1844  call assert_equal('I', g:autocmd)
1845
1846  let g:autocmd = ''
1847  call feedkeys("Sf", 'tnix')
1848  call assert_equal('II', g:autocmd)
1849
1850  let g:autocmd = ''
1851  call feedkeys("Sf\<C-N>", 'tnix')
1852  call assert_equal('IIP', g:autocmd)
1853
1854  let g:autocmd = ''
1855  call feedkeys("Sf\<C-N>\<C-N>", 'tnix')
1856  call assert_equal('IIPP', g:autocmd)
1857
1858  let g:autocmd = ''
1859  call feedkeys("Sf\<C-N>\<C-N>\<C-N>", 'tnix')
1860  call assert_equal('IIPPP', g:autocmd)
1861
1862  let g:autocmd = ''
1863  call feedkeys("Sf\<C-N>\<C-N>\<C-N>\<C-N>", 'tnix')
1864  call assert_equal('IIPPPP', g:autocmd)
1865
1866  call assert_equal(['foo', 'bar', 'foobar', 'foo'], getline(1, '$'))
1867  " TODO: how should it handle completeopt=noinsert,noselect?
1868
1869  " CleanUp
1870  call test_override("char_avail", 0)
1871  au! TextChanged
1872  au! TextChangedI
1873  au! TextChangedP
1874  delfu TextChangedAutocmd
1875  unlet! g:autocmd
1876  set complete&vim completeopt&vim
1877
1878  bw!
1879endfunc
1880
1881let g:setline_handled = v:false
1882func SetLineOne()
1883  if !g:setline_handled
1884    call setline(1, "(x)")
1885    let g:setline_handled = v:true
1886  endif
1887endfunc
1888
1889func Test_TextChangedI_with_setline()
1890  new
1891  call test_override('char_avail', 1)
1892  autocmd TextChangedI <buffer> call SetLineOne()
1893  call feedkeys("i(\<CR>\<Esc>", 'tx')
1894  call assert_equal('(', getline(1))
1895  call assert_equal('x)', getline(2))
1896  undo
1897  call assert_equal('', getline(1))
1898  call assert_equal('', getline(2))
1899
1900  call test_override('starting', 0)
1901  bwipe!
1902endfunc
1903
1904func Test_Changed_FirstTime()
1905  CheckFeature terminal
1906  CheckNotGui
1907  " Starting a terminal to run Vim is always considered flaky.
1908  let g:test_is_flaky = 1
1909
1910  " Prepare file for TextChanged event.
1911  call writefile([''], 'Xchanged.txt')
1912  let buf = term_start([GetVimProg(), '--clean', '-c', 'set noswapfile'], {'term_rows': 3})
1913  call assert_equal('running', term_getstatus(buf))
1914  " Wait for the ruler (in the status line) to be shown.
1915  " In ConPTY, there is additional character which is drawn up to the width of
1916  " the screen.
1917  if has('conpty')
1918    call WaitForAssert({-> assert_match('\<All.*$', term_getline(buf, 3))})
1919  else
1920    call WaitForAssert({-> assert_match('\<All$', term_getline(buf, 3))})
1921  endif
1922  " It's only adding autocmd, so that no event occurs.
1923  call term_sendkeys(buf, ":au! TextChanged <buffer> call writefile(['No'], 'Xchanged.txt')\<cr>")
1924  call term_sendkeys(buf, "\<C-\\>\<C-N>:qa!\<cr>")
1925  call WaitForAssert({-> assert_equal('finished', term_getstatus(buf))})
1926  call assert_equal([''], readfile('Xchanged.txt'))
1927
1928  " clean up
1929  call delete('Xchanged.txt')
1930  bwipe!
1931endfunc
1932
1933func Test_autocmd_nested()
1934  let g:did_nested = 0
1935  augroup Testing
1936    au WinNew * edit somefile
1937    au BufNew * let g:did_nested = 1
1938  augroup END
1939  split
1940  call assert_equal(0, g:did_nested)
1941  close
1942  bwipe! somefile
1943
1944  " old nested argument still works
1945  augroup Testing
1946    au!
1947    au WinNew * nested edit somefile
1948    au BufNew * let g:did_nested = 1
1949  augroup END
1950  split
1951  call assert_equal(1, g:did_nested)
1952  close
1953  bwipe! somefile
1954
1955  " New ++nested argument works
1956  augroup Testing
1957    au!
1958    au WinNew * ++nested edit somefile
1959    au BufNew * let g:did_nested = 1
1960  augroup END
1961  split
1962  call assert_equal(1, g:did_nested)
1963  close
1964  bwipe! somefile
1965
1966  augroup Testing
1967    au!
1968  augroup END
1969
1970  call assert_fails('au WinNew * ++nested ++nested echo bad', 'E983:')
1971  call assert_fails('au WinNew * nested nested echo bad', 'E983:')
1972endfunc
1973
1974func Test_autocmd_once()
1975  " Without ++once WinNew triggers twice
1976  let g:did_split = 0
1977  augroup Testing
1978    au WinNew * let g:did_split += 1
1979  augroup END
1980  split
1981  split
1982  call assert_equal(2, g:did_split)
1983  call assert_true(exists('#WinNew'))
1984  close
1985  close
1986
1987  " With ++once WinNew triggers once
1988  let g:did_split = 0
1989  augroup Testing
1990    au!
1991    au WinNew * ++once let g:did_split += 1
1992  augroup END
1993  split
1994  split
1995  call assert_equal(1, g:did_split)
1996  call assert_false(exists('#WinNew'))
1997  close
1998  close
1999
2000  call assert_fails('au WinNew * ++once ++once echo bad', 'E983:')
2001endfunc
2002
2003func Test_autocmd_bufreadpre()
2004  new
2005  let b:bufreadpre = 1
2006  call append(0, range(1000))
2007  w! XAutocmdBufReadPre.txt
2008  autocmd BufReadPre <buffer> :let b:bufreadpre += 1
2009  norm! 500gg
2010  sp
2011  norm! 1000gg
2012  wincmd p
2013  let g:wsv1 = winsaveview()
2014  wincmd p
2015  let g:wsv2 = winsaveview()
2016  " triggers BufReadPre, should not move the cursor in either window
2017  " The topline may change one line in a large window.
2018  edit
2019  call assert_inrange(g:wsv2.topline - 1, g:wsv2.topline + 1, winsaveview().topline)
2020  call assert_equal(g:wsv2.lnum, winsaveview().lnum)
2021  call assert_equal(2, b:bufreadpre)
2022  wincmd p
2023  call assert_equal(g:wsv1.topline, winsaveview().topline)
2024  call assert_equal(g:wsv1.lnum, winsaveview().lnum)
2025  call assert_equal(2, b:bufreadpre)
2026  " Now set the cursor position in an BufReadPre autocommand
2027  " (even though the position will be invalid, this should make Vim reset the
2028  " cursor position in the other window.
2029  wincmd p
2030  set cpo+=g
2031  " won't do anything, but try to set the cursor on an invalid lnum
2032  autocmd BufReadPre <buffer> :norm! 70gg
2033  " triggers BufReadPre, should not move the cursor in either window
2034  e
2035  call assert_equal(1, winsaveview().topline)
2036  call assert_equal(1, winsaveview().lnum)
2037  call assert_equal(3, b:bufreadpre)
2038  wincmd p
2039  call assert_equal(g:wsv1.topline, winsaveview().topline)
2040  call assert_equal(g:wsv1.lnum, winsaveview().lnum)
2041  call assert_equal(3, b:bufreadpre)
2042  close
2043  close
2044  call delete('XAutocmdBufReadPre.txt')
2045  set cpo-=g
2046endfunc
2047
2048" FileChangedShell tested in test_filechanged.vim
2049
2050" Tests for the following autocommands:
2051" - FileWritePre	writing a compressed file
2052" - FileReadPost	reading a compressed file
2053" - BufNewFile		reading a file template
2054" - BufReadPre		decompressing the file to be read
2055" - FilterReadPre	substituting characters in the temp file
2056" - FilterReadPost	substituting characters after filtering
2057" - FileReadPre		set options for decompression
2058" - FileReadPost	decompress the file
2059func Test_ReadWrite_Autocmds()
2060  " Run this test only on Unix-like systems and if gzip is available
2061  if !has('unix') || !executable("gzip")
2062    return
2063  endif
2064
2065  " Make $GZIP empty, "-v" would cause trouble.
2066  let $GZIP = ""
2067
2068  " Use a FileChangedShell autocommand to avoid a prompt for 'Xtestfile.gz'
2069  " being modified outside of Vim (noticed on Solaris).
2070  au FileChangedShell * echo 'caught FileChangedShell'
2071
2072  " Test for the FileReadPost, FileWritePre and FileWritePost autocmds
2073  augroup Test1
2074    au!
2075    au FileWritePre    *.gz   '[,']!gzip
2076    au FileWritePost   *.gz   undo
2077    au FileReadPost    *.gz   '[,']!gzip -d
2078  augroup END
2079
2080  new
2081  set bin
2082  call append(0, [
2083	      \ 'line 2	Abcdefghijklmnopqrstuvwxyz',
2084	      \ 'line 3	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2085	      \ 'line 4	Abcdefghijklmnopqrstuvwxyz',
2086	      \ 'line 5	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2087	      \ 'line 6	Abcdefghijklmnopqrstuvwxyz',
2088	      \ 'line 7	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2089	      \ 'line 8	Abcdefghijklmnopqrstuvwxyz',
2090	      \ 'line 9	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2091	      \ 'line 10 Abcdefghijklmnopqrstuvwxyz'
2092	      \ ])
2093  1,9write! Xtestfile.gz
2094  enew! | close
2095
2096  new
2097  " Read and decompress the testfile
2098  0read Xtestfile.gz
2099  call assert_equal([
2100	      \ 'line 2	Abcdefghijklmnopqrstuvwxyz',
2101	      \ 'line 3	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2102	      \ 'line 4	Abcdefghijklmnopqrstuvwxyz',
2103	      \ 'line 5	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2104	      \ 'line 6	Abcdefghijklmnopqrstuvwxyz',
2105	      \ 'line 7	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2106	      \ 'line 8	Abcdefghijklmnopqrstuvwxyz',
2107	      \ 'line 9	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2108	      \ 'line 10 Abcdefghijklmnopqrstuvwxyz'
2109	      \ ], getline(1, 9))
2110  enew! | close
2111
2112  augroup Test1
2113    au!
2114  augroup END
2115
2116  " Test for the FileAppendPre and FileAppendPost autocmds
2117  augroup Test2
2118    au!
2119    au BufNewFile      *.c    read Xtest.c
2120    au FileAppendPre   *.out  '[,']s/new/NEW/
2121    au FileAppendPost  *.out  !cat Xtest.c >> test.out
2122  augroup END
2123
2124  call writefile(['/*', ' * Here is a new .c file', ' */'], 'Xtest.c')
2125  new foo.c			" should load Xtest.c
2126  call assert_equal(['/*', ' * Here is a new .c file', ' */'], getline(2, 4))
2127  w! >> test.out		" append it to the output file
2128
2129  let contents = readfile('test.out')
2130  call assert_equal(' * Here is a NEW .c file', contents[2])
2131  call assert_equal(' * Here is a new .c file', contents[5])
2132
2133  call delete('test.out')
2134  enew! | close
2135  augroup Test2
2136    au!
2137  augroup END
2138
2139  " Test for the BufReadPre and BufReadPost autocmds
2140  augroup Test3
2141    au!
2142    " setup autocommands to decompress before reading and re-compress
2143    " afterwards
2144    au BufReadPre  *.gz  exe '!gzip -d ' . shellescape(expand("<afile>"))
2145    au BufReadPre  *.gz  call rename(expand("<afile>:r"), expand("<afile>"))
2146    au BufReadPost *.gz  call rename(expand("<afile>"), expand("<afile>:r"))
2147    au BufReadPost *.gz  exe '!gzip ' . shellescape(expand("<afile>:r"))
2148  augroup END
2149
2150  e! Xtestfile.gz		" Edit compressed file
2151  call assert_equal([
2152	      \ 'line 2	Abcdefghijklmnopqrstuvwxyz',
2153	      \ 'line 3	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2154	      \ 'line 4	Abcdefghijklmnopqrstuvwxyz',
2155	      \ 'line 5	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2156	      \ 'line 6	Abcdefghijklmnopqrstuvwxyz',
2157	      \ 'line 7	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2158	      \ 'line 8	Abcdefghijklmnopqrstuvwxyz',
2159	      \ 'line 9	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2160	      \ 'line 10 Abcdefghijklmnopqrstuvwxyz'
2161	      \ ], getline(1, 9))
2162
2163  w! >> test.out		" Append it to the output file
2164
2165  augroup Test3
2166    au!
2167  augroup END
2168
2169  " Test for the FilterReadPre and FilterReadPost autocmds.
2170  set shelltemp			" need temp files here
2171  augroup Test4
2172    au!
2173    au FilterReadPre   *.out  call rename(expand("<afile>"), expand("<afile>") . ".t")
2174    au FilterReadPre   *.out  exe 'silent !sed s/e/E/ ' . shellescape(expand("<afile>")) . ".t >" . shellescape(expand("<afile>"))
2175    au FilterReadPre   *.out  exe 'silent !rm ' . shellescape(expand("<afile>")) . '.t'
2176    au FilterReadPost  *.out  '[,']s/x/X/g
2177  augroup END
2178
2179  e! test.out			" Edit the output file
2180  1,$!cat
2181  call assert_equal([
2182	      \ 'linE 2	AbcdefghijklmnopqrstuvwXyz',
2183	      \ 'linE 3	XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
2184	      \ 'linE 4	AbcdefghijklmnopqrstuvwXyz',
2185	      \ 'linE 5	XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
2186	      \ 'linE 6	AbcdefghijklmnopqrstuvwXyz',
2187	      \ 'linE 7	XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
2188	      \ 'linE 8	AbcdefghijklmnopqrstuvwXyz',
2189	      \ 'linE 9	XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
2190	      \ 'linE 10 AbcdefghijklmnopqrstuvwXyz'
2191	      \ ], getline(1, 9))
2192  call assert_equal([
2193	      \ 'line 2	Abcdefghijklmnopqrstuvwxyz',
2194	      \ 'line 3	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2195	      \ 'line 4	Abcdefghijklmnopqrstuvwxyz',
2196	      \ 'line 5	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2197	      \ 'line 6	Abcdefghijklmnopqrstuvwxyz',
2198	      \ 'line 7	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2199	      \ 'line 8	Abcdefghijklmnopqrstuvwxyz',
2200	      \ 'line 9	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2201	      \ 'line 10 Abcdefghijklmnopqrstuvwxyz'
2202	      \ ], readfile('test.out'))
2203
2204  augroup Test4
2205    au!
2206  augroup END
2207  set shelltemp&vim
2208
2209  " Test for the FileReadPre and FileReadPost autocmds.
2210  augroup Test5
2211    au!
2212    au FileReadPre *.gz exe 'silent !gzip -d ' . shellescape(expand("<afile>"))
2213    au FileReadPre *.gz call rename(expand("<afile>:r"), expand("<afile>"))
2214    au FileReadPost *.gz '[,']s/l/L/
2215  augroup END
2216
2217  new
2218  0r Xtestfile.gz		" Read compressed file
2219  call assert_equal([
2220	      \ 'Line 2	Abcdefghijklmnopqrstuvwxyz',
2221	      \ 'Line 3	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2222	      \ 'Line 4	Abcdefghijklmnopqrstuvwxyz',
2223	      \ 'Line 5	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2224	      \ 'Line 6	Abcdefghijklmnopqrstuvwxyz',
2225	      \ 'Line 7	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2226	      \ 'Line 8	Abcdefghijklmnopqrstuvwxyz',
2227	      \ 'Line 9	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2228	      \ 'Line 10 Abcdefghijklmnopqrstuvwxyz'
2229	      \ ], getline(1, 9))
2230  call assert_equal([
2231	      \ 'line 2	Abcdefghijklmnopqrstuvwxyz',
2232	      \ 'line 3	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2233	      \ 'line 4	Abcdefghijklmnopqrstuvwxyz',
2234	      \ 'line 5	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2235	      \ 'line 6	Abcdefghijklmnopqrstuvwxyz',
2236	      \ 'line 7	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2237	      \ 'line 8	Abcdefghijklmnopqrstuvwxyz',
2238	      \ 'line 9	xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
2239	      \ 'line 10 Abcdefghijklmnopqrstuvwxyz'
2240	      \ ], readfile('Xtestfile.gz'))
2241
2242  augroup Test5
2243    au!
2244  augroup END
2245
2246  au! FileChangedShell
2247  call delete('Xtestfile.gz')
2248  call delete('Xtest.c')
2249  call delete('test.out')
2250endfunc
2251
2252func Test_throw_in_BufWritePre()
2253  new
2254  call setline(1, ['one', 'two', 'three'])
2255  call assert_false(filereadable('Xthefile'))
2256  augroup throwing
2257    au BufWritePre X* throw 'do not write'
2258  augroup END
2259  try
2260    w Xthefile
2261  catch
2262    let caught = 1
2263  endtry
2264  call assert_equal(1, caught)
2265  call assert_false(filereadable('Xthefile'))
2266
2267  bwipe!
2268  au! throwing
2269endfunc
2270
2271func Test_autocmd_SafeState()
2272  CheckRunVimInTerminal
2273
2274  let lines =<< trim END
2275	let g:safe = 0
2276	let g:again = ''
2277	au SafeState * let g:safe += 1
2278	au SafeStateAgain * let g:again ..= 'x'
2279	func CallTimer()
2280	  call timer_start(10, {id -> execute('let g:again ..= "t"')})
2281	endfunc
2282  END
2283  call writefile(lines, 'XSafeState')
2284  let buf = RunVimInTerminal('-S XSafeState', #{rows: 6})
2285
2286  " Sometimes we loop to handle a K_IGNORE, SafeState may be trigered once or
2287  " more often.
2288  call term_sendkeys(buf, ":echo g:safe\<CR>")
2289  call WaitForAssert({-> assert_match('^\d ', term_getline(buf, 6))}, 1000)
2290
2291  " SafeStateAgain should be invoked at least three times
2292  call term_sendkeys(buf, ":echo g:again\<CR>")
2293  call WaitForAssert({-> assert_match('^xxx', term_getline(buf, 6))}, 1000)
2294
2295  call term_sendkeys(buf, ":let g:again = ''\<CR>:call CallTimer()\<CR>")
2296  call TermWait(buf, 50)
2297  call term_sendkeys(buf, ":\<CR>")
2298  call TermWait(buf, 50)
2299  call term_sendkeys(buf, ":echo g:again\<CR>")
2300  call WaitForAssert({-> assert_match('xtx', term_getline(buf, 6))}, 1000)
2301
2302  call StopVimInTerminal(buf)
2303  call delete('XSafeState')
2304endfunc
2305
2306func Test_autocmd_CmdWinEnter()
2307  CheckRunVimInTerminal
2308  " There is not cmdwin switch, so
2309  " test for cmdline_hist
2310  " (both are available with small builds)
2311  CheckFeature cmdline_hist
2312  let lines =<< trim END
2313    let b:dummy_var = 'This is a dummy'
2314    autocmd CmdWinEnter * quit
2315    let winnr = winnr('$')
2316  END
2317  let filename='XCmdWinEnter'
2318  call writefile(lines, filename)
2319  let buf = RunVimInTerminal('-S '.filename, #{rows: 6})
2320
2321  call term_sendkeys(buf, "q:")
2322  call TermWait(buf)
2323  call term_sendkeys(buf, ":echo b:dummy_var\<cr>")
2324  call WaitForAssert({-> assert_match('^This is a dummy', term_getline(buf, 6))}, 2000)
2325  call term_sendkeys(buf, ":echo &buftype\<cr>")
2326  call WaitForAssert({-> assert_notmatch('^nofile', term_getline(buf, 6))}, 1000)
2327  call term_sendkeys(buf, ":echo winnr\<cr>")
2328  call WaitForAssert({-> assert_match('^1', term_getline(buf, 6))}, 1000)
2329
2330  " clean up
2331  call StopVimInTerminal(buf)
2332  call delete(filename)
2333endfunc
2334
2335func Test_autocmd_was_using_freed_memory()
2336  CheckFeature quickfix
2337
2338  pedit xx
2339  n x
2340  au WinEnter * quit
2341  split
2342  au! WinEnter
2343endfunc
2344
2345func Test_BufWrite_lockmarks()
2346  edit! Xtest
2347  call setline(1, ['a', 'b', 'c', 'd'])
2348
2349  " :lockmarks preserves the marks
2350  call SetChangeMarks(2, 3)
2351  lockmarks write
2352  call assert_equal([2, 3], [line("'["), line("']")])
2353
2354  " *WritePre autocmds get the correct line range, but lockmarks preserves the
2355  " original values for the user
2356  augroup lockmarks
2357    au!
2358    au BufWritePre,FilterWritePre * call assert_equal([1, 4], [line("'["), line("']")])
2359    au FileWritePre * call assert_equal([3, 4], [line("'["), line("']")])
2360  augroup END
2361
2362  lockmarks write
2363  call assert_equal([2, 3], [line("'["), line("']")])
2364
2365  if executable('cat')
2366    lockmarks %!cat
2367    call assert_equal([2, 3], [line("'["), line("']")])
2368  endif
2369
2370  lockmarks 3,4write Xtest2
2371  call assert_equal([2, 3], [line("'["), line("']")])
2372
2373  au! lockmarks
2374  augroup! lockmarks
2375  call delete('Xtest')
2376  call delete('Xtest2')
2377endfunc
2378
2379func Test_FileType_spell()
2380  if !isdirectory('/tmp')
2381    throw "Skipped: requires /tmp directory"
2382  endif
2383
2384  " this was crashing with an invalid free()
2385  setglobal spellfile=/tmp/en.utf-8.add
2386  augroup crash
2387    autocmd!
2388    autocmd BufNewFile,BufReadPost crashfile setf somefiletype
2389    autocmd BufNewFile,BufReadPost crashfile set ft=anotherfiletype
2390    autocmd FileType anotherfiletype setlocal spell
2391  augroup END
2392  func! NoCrash() abort
2393    edit /tmp/crashfile
2394  endfunc
2395  call NoCrash()
2396
2397  au! crash
2398  setglobal spellfile=
2399endfunc
2400
2401" Test closing a window or editing another buffer from a FileChangedRO handler
2402" in a readonly buffer
2403func Test_FileChangedRO_winclose()
2404  augroup FileChangedROTest
2405    au!
2406    autocmd FileChangedRO * quit
2407  augroup END
2408  new
2409  set readonly
2410  call assert_fails('normal i', 'E788:')
2411  close
2412  augroup! FileChangedROTest
2413
2414  augroup FileChangedROTest
2415    au!
2416    autocmd FileChangedRO * edit Xfile
2417  augroup END
2418  new
2419  set readonly
2420  call assert_fails('normal i', 'E788:')
2421  close
2422  augroup! FileChangedROTest
2423endfunc
2424
2425func LogACmd()
2426  call add(g:logged, line('$'))
2427endfunc
2428
2429func Test_TermChanged()
2430  CheckNotGui
2431
2432  enew!
2433  tabnew
2434  call setline(1, ['a', 'b', 'c', 'd'])
2435  $
2436  au TermChanged * call LogACmd()
2437  let g:logged = []
2438  let term_save = &term
2439  set term=xterm
2440  call assert_equal([1, 4], g:logged)
2441
2442  au! TermChanged
2443  let &term = term_save
2444  bwipe!
2445endfunc
2446
2447" Test for FileReadCmd autocmd
2448func Test_autocmd_FileReadCmd()
2449  func ReadFileCmd()
2450    call append(line('$'), "v:cmdarg = " .. v:cmdarg)
2451  endfunc
2452  augroup FileReadCmdTest
2453    au!
2454    au FileReadCmd Xtest call ReadFileCmd()
2455  augroup END
2456
2457  new
2458  read ++bin Xtest
2459  read ++nobin Xtest
2460  read ++edit Xtest
2461  read ++bad=keep Xtest
2462  read ++bad=drop Xtest
2463  read ++bad=- Xtest
2464  read ++ff=unix Xtest
2465  read ++ff=dos Xtest
2466  read ++ff=mac Xtest
2467  read ++enc=utf-8 Xtest
2468
2469  call assert_equal(['',
2470        \ 'v:cmdarg =  ++bin',
2471        \ 'v:cmdarg =  ++nobin',
2472        \ 'v:cmdarg =  ++edit',
2473        \ 'v:cmdarg =  ++bad=keep',
2474        \ 'v:cmdarg =  ++bad=drop',
2475        \ 'v:cmdarg =  ++bad=-',
2476        \ 'v:cmdarg =  ++ff=unix',
2477        \ 'v:cmdarg =  ++ff=dos',
2478        \ 'v:cmdarg =  ++ff=mac',
2479        \ 'v:cmdarg =  ++enc=utf-8'], getline(1, '$'))
2480
2481  close!
2482  augroup FileReadCmdTest
2483    au!
2484  augroup END
2485  delfunc ReadFileCmd
2486endfunc
2487
2488" Test for passing invalid arguments to autocmd
2489func Test_autocmd_invalid_args()
2490  " Additional character after * for event
2491  call assert_fails('autocmd *a Xfile set ff=unix', 'E215:')
2492  augroup Test
2493  augroup END
2494  " Invalid autocmd event
2495  call assert_fails('autocmd Bufabc Xfile set ft=vim', 'E216:')
2496  " Invalid autocmd event in a autocmd group
2497  call assert_fails('autocmd Test Bufabc Xfile set ft=vim', 'E216:')
2498  augroup! Test
2499  " Execute all autocmds
2500  call assert_fails('doautocmd * BufEnter', 'E217:')
2501  call assert_fails('augroup! x1a2b3', 'E367:')
2502  call assert_fails('autocmd BufNew <buffer=999> pwd', 'E680:')
2503endfunc
2504
2505" Test for deep nesting of autocmds
2506func Test_autocmd_deep_nesting()
2507  autocmd BufEnter Xfile doautocmd BufEnter Xfile
2508  call assert_fails('doautocmd BufEnter Xfile', 'E218:')
2509  autocmd! BufEnter Xfile
2510endfunc
2511
2512" vim: shiftwidth=2 sts=2 expandtab
2513