comparison src/testdir/test_autocmd.vim @ 23865:e1643a1aa1a0 v8.2.2474

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