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