diff options
Diffstat (limited to 'test/old/testdir/test_autocmd.vim')
| -rw-r--r-- | test/old/testdir/test_autocmd.vim | 3825 |
1 files changed, 3825 insertions, 0 deletions
diff --git a/test/old/testdir/test_autocmd.vim b/test/old/testdir/test_autocmd.vim new file mode 100644 index 0000000000..7926411dcd --- /dev/null +++ b/test/old/testdir/test_autocmd.vim @@ -0,0 +1,3825 @@ +" Tests for autocommands + +source shared.vim +source check.vim +source term_util.vim +source screendump.vim +source vim9.vim +source load.vim + +func s:cleanup_buffers() abort + for bnr in range(1, bufnr('$')) + if bufloaded(bnr) && bufnr('%') != bnr + execute 'bd! ' . bnr + endif + endfor +endfunc + +func Test_vim_did_enter() + call assert_false(v:vim_did_enter) + + " This script will never reach the main loop, can't check if v:vim_did_enter + " becomes one. +endfunc + +" Test for the CursorHold autocmd +func Test_CursorHold_autocmd() + CheckRunVimInTerminal + call writefile(['one', 'two', 'three'], 'XoneTwoThree', 'D') + let before =<< trim END + set updatetime=10 + au CursorHold * call writefile([line('.')], 'XCHoutput', 'a') + END + call writefile(before, 'XCHinit', 'D') + let buf = RunVimInTerminal('-S XCHinit XoneTwoThree', {}) + call term_sendkeys(buf, "G") + call term_wait(buf, 50) + call term_sendkeys(buf, "gg") + call term_wait(buf) + call WaitForAssert({-> assert_equal(['1'], readfile('XCHoutput')[-1:-1])}) + call term_sendkeys(buf, "j") + call term_wait(buf) + call WaitForAssert({-> assert_equal(['1', '2'], readfile('XCHoutput')[-2:-1])}) + call term_sendkeys(buf, "j") + call term_wait(buf) + call WaitForAssert({-> assert_equal(['1', '2', '3'], readfile('XCHoutput')[-3:-1])}) + call StopVimInTerminal(buf) + + call delete('XCHoutput') +endfunc + +if has('timers') + + func ExitInsertMode(id) + call feedkeys("\<Esc>") + endfunc + + func Test_cursorhold_insert() + " depends on timing + let g:test_is_flaky = 1 + + " Need to move the cursor. + call feedkeys("ggG", "xt") + + let g:triggered = 0 + au CursorHoldI * let g:triggered += 1 + set updatetime=20 + call timer_start(LoadAdjust(200), 'ExitInsertMode') + call feedkeys('a', 'x!') + call assert_equal(1, g:triggered) + unlet g:triggered + au! CursorHoldI + set updatetime& + endfunc + + func Test_cursorhold_insert_with_timer_interrupt() + CheckFeature job + " Need to move the cursor. + call feedkeys("ggG", "xt") + + " Confirm the timer invoked in exit_cb of the job doesn't disturb + " CursorHoldI event. + let g:triggered = 0 + au CursorHoldI * let g:triggered += 1 + set updatetime=500 + call job_start(has('win32') ? 'cmd /c echo:' : 'echo', + \ {'exit_cb': {-> timer_start(1000, 'ExitInsertMode')}}) + call feedkeys('a', 'x!') + call assert_equal(1, g:triggered) + unlet g:triggered + au! CursorHoldI + set updatetime& + endfunc + + func Test_cursorhold_insert_ctrl_x() + let g:triggered = 0 + au CursorHoldI * let g:triggered += 1 + set updatetime=20 + call timer_start(LoadAdjust(100), 'ExitInsertMode') + " CursorHoldI does not trigger after CTRL-X + call feedkeys("a\<C-X>", 'x!') + call assert_equal(0, g:triggered) + unlet g:triggered + au! CursorHoldI + set updatetime& + endfunc + + func Test_cursorhold_insert_ctrl_g_U() + au CursorHoldI * : + set updatetime=20 + new + call timer_start(100, { -> feedkeys("\<Left>foo\<Esc>", 't') }) + call feedkeys("i()\<C-g>U", 'tx!') + sleep 200m + call assert_equal('(foo)', getline(1)) + undo + call assert_equal('', getline(1)) + + bwipe! + au! CursorHoldI + set updatetime& + endfunc + + func Test_OptionSet_modeline() + CheckFunction test_override + call test_override('starting', 1) + au! OptionSet + augroup set_tabstop + au OptionSet tabstop call timer_start(1, {-> execute("echo 'Handler called'", "")}) + augroup END + call writefile(['vim: set ts=7 sw=5 :', 'something'], 'XoptionsetModeline', 'D') + set modeline + let v:errmsg = '' + call assert_fails('split XoptionsetModeline', 'E12:') + call assert_equal(7, &ts) + call assert_equal('', v:errmsg) + + augroup set_tabstop + au! + augroup END + bwipe! + set ts& + call test_override('starting', 0) + endfunc + +endif "has('timers') + +func Test_bufunload() + augroup test_bufunload_group + autocmd! + autocmd BufUnload * call add(s:li, "bufunload") + autocmd BufDelete * call add(s:li, "bufdelete") + autocmd BufWipeout * call add(s:li, "bufwipeout") + augroup END + + let s:li = [] + new + setlocal bufhidden= + bunload + call assert_equal(["bufunload", "bufdelete"], s:li) + + let s:li = [] + new + setlocal bufhidden=delete + bunload + call assert_equal(["bufunload", "bufdelete"], s:li) + + let s:li = [] + new + setlocal bufhidden=unload + bwipeout + call assert_equal(["bufunload", "bufdelete", "bufwipeout"], s:li) + + au! test_bufunload_group + augroup! test_bufunload_group +endfunc + +" SEGV occurs in older versions. (At least 7.4.2005 or older) +func Test_autocmd_bufunload_with_tabnext() + tabedit + tabfirst + + augroup test_autocmd_bufunload_with_tabnext_group + autocmd! + autocmd BufUnload <buffer> tabnext + augroup END + + quit + call assert_equal(2, tabpagenr('$')) + + autocmd! test_autocmd_bufunload_with_tabnext_group + augroup! test_autocmd_bufunload_with_tabnext_group + tablast + quit +endfunc + +func Test_argdelete_in_next() + au BufNew,BufEnter,BufLeave,BufWinEnter * argdel + call assert_fails('next a b', 'E1156:') + au! BufNew,BufEnter,BufLeave,BufWinEnter * +endfunc + +func Test_autocmd_bufwinleave_with_tabfirst() + tabedit + augroup sample + autocmd! + autocmd BufWinLeave <buffer> tabfirst + augroup END + call setline(1, ['a', 'b', 'c']) + edit! a.txt + tabclose +endfunc + +" SEGV occurs in older versions. (At least 7.4.2321 or older) +func Test_autocmd_bufunload_avoiding_SEGV_01() + split aa.txt + let lastbuf = bufnr('$') + + augroup test_autocmd_bufunload + autocmd! + exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!' + augroup END + + call assert_fails('edit bb.txt', 'E937:') + + autocmd! test_autocmd_bufunload + augroup! test_autocmd_bufunload + bwipe! aa.txt + bwipe! bb.txt +endfunc + +" SEGV occurs in older versions. (At least 7.4.2321 or older) +func Test_autocmd_bufunload_avoiding_SEGV_02() + setlocal buftype=nowrite + let lastbuf = bufnr('$') + + augroup test_autocmd_bufunload + autocmd! + exe 'autocmd BufUnload <buffer> ' . (lastbuf + 1) . 'bwipeout!' + augroup END + + normal! i1 + call assert_fails('edit a.txt', 'E517:') + + autocmd! test_autocmd_bufunload + augroup! test_autocmd_bufunload + bwipe! a.txt +endfunc + +func Test_autocmd_dummy_wipeout() + " prepare files + call writefile([''], 'Xdummywipetest1.txt', 'D') + call writefile([''], 'Xdummywipetest2.txt', 'D') + augroup test_bufunload_group + autocmd! + autocmd BufUnload * call add(s:li, "bufunload") + autocmd BufDelete * call add(s:li, "bufdelete") + autocmd BufWipeout * call add(s:li, "bufwipeout") + augroup END + + let s:li = [] + split Xdummywipetest1.txt + silent! vimgrep /notmatched/ Xdummywipetest* + call assert_equal(["bufunload", "bufwipeout"], s:li) + + bwipeout + au! test_bufunload_group + augroup! test_bufunload_group +endfunc + +func Test_win_tab_autocmd() + let g:record = [] + + augroup testing + au WinNew * call add(g:record, 'WinNew') + au WinClosed * call add(g:record, 'WinClosed') + au WinEnter * call add(g:record, 'WinEnter') + au WinLeave * call add(g:record, 'WinLeave') + au TabNew * call add(g:record, 'TabNew') + au TabClosed * call add(g:record, 'TabClosed') + au TabEnter * call add(g:record, 'TabEnter') + au TabLeave * call add(g:record, 'TabLeave') + augroup END + + split + tabnew + close + close + + call assert_equal([ + \ 'WinLeave', 'WinNew', 'WinEnter', + \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter', + \ 'WinLeave', 'TabLeave', 'WinClosed', 'TabClosed', 'WinEnter', 'TabEnter', + \ 'WinLeave', 'WinClosed', 'WinEnter' + \ ], g:record) + + let g:record = [] + tabnew somefile + tabnext + bwipe somefile + + call assert_equal([ + \ 'WinLeave', 'TabLeave', 'WinNew', 'WinEnter', 'TabNew', 'TabEnter', + \ 'WinLeave', 'TabLeave', 'WinEnter', 'TabEnter', + \ 'WinClosed', 'TabClosed' + \ ], g:record) + + augroup testing + au! + augroup END + unlet g:record +endfunc + +func Test_WinResized() + CheckRunVimInTerminal + + let lines =<< trim END + set scrolloff=0 + call setline(1, ['111', '222']) + vnew + call setline(1, ['aaa', 'bbb']) + new + call setline(1, ['foo', 'bar']) + + let g:resized = 0 + au WinResized * let g:resized += 1 + + func WriteResizedEvent() + call writefile([json_encode(v:event)], 'XresizeEvent') + endfunc + au WinResized * call WriteResizedEvent() + END + call writefile(lines, 'Xtest_winresized', 'D') + let buf = RunVimInTerminal('-S Xtest_winresized', {'rows': 10}) + + " redraw now to avoid a redraw after the :echo command + call term_sendkeys(buf, ":redraw!\<CR>") + call TermWait(buf) + + call term_sendkeys(buf, ":echo g:resized\<CR>") + call WaitForAssert({-> assert_match('^0$', term_getline(buf, 10))}, 1000) + + " increase window height, two windows will be reported + call term_sendkeys(buf, "\<C-W>+") + call TermWait(buf) + call term_sendkeys(buf, ":echo g:resized\<CR>") + call WaitForAssert({-> assert_match('^1$', term_getline(buf, 10))}, 1000) + + let event = readfile('XresizeEvent')[0]->json_decode() + call assert_equal({ + \ 'windows': [1002, 1001], + \ }, event) + + " increase window width, three windows will be reported + call term_sendkeys(buf, "\<C-W>>") + call TermWait(buf) + call term_sendkeys(buf, ":echo g:resized\<CR>") + call WaitForAssert({-> assert_match('^2$', term_getline(buf, 10))}, 1000) + + let event = readfile('XresizeEvent')[0]->json_decode() + call assert_equal({ + \ 'windows': [1002, 1001, 1000], + \ }, event) + + call delete('XresizeEvent') + call StopVimInTerminal(buf) +endfunc + +func Test_WinScrolled() + CheckRunVimInTerminal + + let lines =<< trim END + set nowrap scrolloff=0 + for ii in range(1, 18) + call setline(ii, repeat(nr2char(96 + ii), ii * 2)) + endfor + let win_id = win_getid() + let g:matched = v:false + func WriteScrollEvent() + call writefile([json_encode(v:event)], 'XscrollEvent') + endfunc + execute 'au WinScrolled' win_id 'let g:matched = v:true' + let g:scrolled = 0 + au WinScrolled * let g:scrolled += 1 + au WinScrolled * let g:amatch = str2nr(expand('<amatch>')) + au WinScrolled * let g:afile = str2nr(expand('<afile>')) + au WinScrolled * call WriteScrollEvent() + END + call writefile(lines, 'Xtest_winscrolled', 'D') + let buf = RunVimInTerminal('-S Xtest_winscrolled', {'rows': 6}) + + call term_sendkeys(buf, ":echo g:scrolled\<CR>") + call WaitForAssert({-> assert_match('^0 ', term_getline(buf, 6))}, 1000) + + " Scroll left/right in Normal mode. + call term_sendkeys(buf, "zlzh:echo g:scrolled\<CR>") + call WaitForAssert({-> assert_match('^2 ', term_getline(buf, 6))}, 1000) + + let event = readfile('XscrollEvent')[0]->json_decode() + call assert_equal({ + \ 'all': {'leftcol': 1, 'topline': 0, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1000': {'leftcol': -1, 'topline': 0, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0} + \ }, event) + + " Scroll up/down in Normal mode. + call term_sendkeys(buf, "\<c-e>\<c-y>:echo g:scrolled\<CR>") + call WaitForAssert({-> assert_match('^4 ', term_getline(buf, 6))}, 1000) + + let event = readfile('XscrollEvent')[0]->json_decode() + call assert_equal({ + \ 'all': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1000': {'leftcol': 0, 'topline': -1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0} + \ }, event) + + " Scroll up/down in Insert mode. + call term_sendkeys(buf, "Mi\<c-x>\<c-e>\<Esc>i\<c-x>\<c-y>\<Esc>") + call term_sendkeys(buf, ":echo g:scrolled\<CR>") + call WaitForAssert({-> assert_match('^6 ', term_getline(buf, 6))}, 1000) + + let event = readfile('XscrollEvent')[0]->json_decode() + call assert_equal({ + \ 'all': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1000': {'leftcol': 0, 'topline': -1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0} + \ }, event) + + " Scroll the window horizontally to focus the last letter of the third line + " containing only six characters. Moving to the previous and shorter lines + " should trigger another autocommand as Vim has to make them visible. + call term_sendkeys(buf, "5zl2k") + call term_sendkeys(buf, ":echo g:scrolled\<CR>") + call WaitForAssert({-> assert_match('^8 ', term_getline(buf, 6))}, 1000) + + let event = readfile('XscrollEvent')[0]->json_decode() + call assert_equal({ + \ 'all': {'leftcol': 5, 'topline': 0, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1000': {'leftcol': -5, 'topline': 0, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0} + \ }, event) + + " Ensure the command was triggered for the specified window ID. + call term_sendkeys(buf, ":echo g:matched\<CR>") + call WaitForAssert({-> assert_match('^v:true ', term_getline(buf, 6))}, 1000) + + " Ensure the expansion of <amatch> and <afile> matches the window ID. + call term_sendkeys(buf, ":echo g:amatch == win_id && g:afile == win_id\<CR>") + call WaitForAssert({-> assert_match('^v:true ', term_getline(buf, 6))}, 1000) + + call delete('XscrollEvent') + call StopVimInTerminal(buf) +endfunc + +func Test_WinScrolled_mouse() + CheckRunVimInTerminal + + let lines =<< trim END + set nowrap scrolloff=0 + set mouse=a term=xterm ttymouse=sgr mousetime=200 clipboard= + call setline(1, ['foo']->repeat(32)) + split + let g:scrolled = 0 + au WinScrolled * let g:scrolled += 1 + END + call writefile(lines, 'Xtest_winscrolled_mouse', 'D') + let buf = RunVimInTerminal('-S Xtest_winscrolled_mouse', {'rows': 10}) + + " With the upper split focused, send a scroll-down event to the unfocused one. + call test_setmouse(7, 1) + call term_sendkeys(buf, "\<ScrollWheelDown>") + call TermWait(buf) + call term_sendkeys(buf, ":echo g:scrolled\<CR>") + call WaitForAssert({-> assert_match('^1', term_getline(buf, 10))}, 1000) + + " Again, but this time while we're in insert mode. + call term_sendkeys(buf, "i\<ScrollWheelDown>\<Esc>") + call TermWait(buf) + call term_sendkeys(buf, ":echo g:scrolled\<CR>") + call WaitForAssert({-> assert_match('^2', term_getline(buf, 10))}, 1000) + + call StopVimInTerminal(buf) +endfunc + +func Test_WinScrolled_close_curwin() + CheckRunVimInTerminal + + let lines =<< trim END + set nowrap scrolloff=0 + call setline(1, ['aaa', 'bbb']) + vsplit + au WinScrolled * close + au VimLeave * call writefile(['123456'], 'Xtestout') + END + call writefile(lines, 'Xtest_winscrolled_close_curwin', 'D') + let buf = RunVimInTerminal('-S Xtest_winscrolled_close_curwin', {'rows': 6}) + + " This was using freed memory + call term_sendkeys(buf, "\<C-E>") + call TermWait(buf) + call StopVimInTerminal(buf) + + " check the startup script finished to the end + call assert_equal(['123456'], readfile('Xtestout')) + call delete('Xtestout') +endfunc + +func Test_WinScrolled_once_only() + CheckRunVimInTerminal + + let lines =<< trim END + set cmdheight=2 + call setline(1, ['aaa', 'bbb']) + let trigger_count = 0 + func ShowInfo(id) + echo g:trigger_count g:winid winlayout() + endfunc + + vsplit + split + " use a timer to show the info after a redraw + au WinScrolled * let trigger_count += 1 | let winid = expand('<amatch>') | call timer_start(100, 'ShowInfo') + wincmd j + wincmd l + END + call writefile(lines, 'Xtest_winscrolled_once', 'D') + let buf = RunVimInTerminal('-S Xtest_winscrolled_once', #{rows: 10, cols: 60, statusoff: 2}) + + call term_sendkeys(buf, "\<C-E>") + call VerifyScreenDump(buf, 'Test_winscrolled_once_only_1', {}) + + call StopVimInTerminal(buf) +endfunc + +" Check that WinScrolled is not triggered immediately when defined and there +" are split windows. +func Test_WinScrolled_not_when_defined() + CheckRunVimInTerminal + + let lines =<< trim END + call setline(1, ['aaa', 'bbb']) + echo 'nothing happened' + func ShowTriggered(id) + echo 'triggered' + endfunc + END + call writefile(lines, 'Xtest_winscrolled_not', 'D') + let buf = RunVimInTerminal('-S Xtest_winscrolled_not', #{rows: 10, cols: 60, statusoff: 2}) + call term_sendkeys(buf, ":split\<CR>") + call TermWait(buf) + " use a timer to show the message after redrawing + call term_sendkeys(buf, ":au WinScrolled * call timer_start(100, 'ShowTriggered')\<CR>") + call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_1', {}) + + call term_sendkeys(buf, "\<C-E>") + call VerifyScreenDump(buf, 'Test_winscrolled_not_when_defined_2', {}) + + call StopVimInTerminal(buf) +endfunc + +func Test_WinScrolled_long_wrapped() + CheckRunVimInTerminal + + let lines =<< trim END + set scrolloff=0 + let height = winheight(0) + let width = winwidth(0) + let g:scrolled = 0 + au WinScrolled * let g:scrolled += 1 + call setline(1, repeat('foo', height * width)) + call cursor(1, height * width) + END + call writefile(lines, 'Xtest_winscrolled_long_wrapped', 'D') + let buf = RunVimInTerminal('-S Xtest_winscrolled_long_wrapped', {'rows': 6}) + + call term_sendkeys(buf, ":echo g:scrolled\<CR>") + call WaitForAssert({-> assert_match('^0 ', term_getline(buf, 6))}, 1000) + + call term_sendkeys(buf, 'gj') + call term_sendkeys(buf, ":echo g:scrolled\<CR>") + call WaitForAssert({-> assert_match('^1 ', term_getline(buf, 6))}, 1000) + + call term_sendkeys(buf, '0') + call term_sendkeys(buf, ":echo g:scrolled\<CR>") + call WaitForAssert({-> assert_match('^2 ', term_getline(buf, 6))}, 1000) + + call term_sendkeys(buf, '$') + call term_sendkeys(buf, ":echo g:scrolled\<CR>") + call WaitForAssert({-> assert_match('^3 ', term_getline(buf, 6))}, 1000) + + call StopVimInTerminal(buf) +endfunc + +func Test_WinScrolled_diff() + CheckRunVimInTerminal + + let lines =<< trim END + set diffopt+=foldcolumn:0 + call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']) + vnew + call setline(1, ['d', 'e', 'f', 'g', 'h', 'i']) + windo diffthis + func WriteScrollEvent() + call writefile([json_encode(v:event)], 'XscrollEvent') + endfunc + au WinScrolled * call WriteScrollEvent() + END + call writefile(lines, 'Xtest_winscrolled_diff', 'D') + let buf = RunVimInTerminal('-S Xtest_winscrolled_diff', {'rows': 8}) + + call term_sendkeys(buf, "\<C-E>") + call WaitForAssert({-> assert_match('^d', term_getline(buf, 3))}, 1000) + + let event = readfile('XscrollEvent')[0]->json_decode() + call assert_equal({ + \ 'all': {'leftcol': 0, 'topline': 1, 'topfill': 1, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1000': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1001': {'leftcol': 0, 'topline': 0, 'topfill': -1, 'width': 0, 'height': 0, 'skipcol': 0} + \ }, event) + + call term_sendkeys(buf, "2\<C-E>") + call WaitForAssert({-> assert_match('^f', term_getline(buf, 3))}, 1000) + + let event = readfile('XscrollEvent')[0]->json_decode() + call assert_equal({ + \ 'all': {'leftcol': 0, 'topline': 2, 'topfill': 2, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1000': {'leftcol': 0, 'topline': 2, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1001': {'leftcol': 0, 'topline': 0, 'topfill': -2, 'width': 0, 'height': 0, 'skipcol': 0} + \ }, event) + + call term_sendkeys(buf, "\<C-E>") + call WaitForAssert({-> assert_match('^g', term_getline(buf, 3))}, 1000) + + let event = readfile('XscrollEvent')[0]->json_decode() + call assert_equal({ + \ 'all': {'leftcol': 0, 'topline': 2, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1000': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1001': {'leftcol': 0, 'topline': 1, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0} + \ }, event) + + call term_sendkeys(buf, "2\<C-Y>") + call WaitForAssert({-> assert_match('^e', term_getline(buf, 3))}, 1000) + + let event = readfile('XscrollEvent')[0]->json_decode() + call assert_equal({ + \ 'all': {'leftcol': 0, 'topline': 3, 'topfill': 1, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1000': {'leftcol': 0, 'topline': -2, 'topfill': 0, 'width': 0, 'height': 0, 'skipcol': 0}, + \ '1001': {'leftcol': 0, 'topline': -1, 'topfill': 1, 'width': 0, 'height': 0, 'skipcol': 0} + \ }, event) + + call StopVimInTerminal(buf) + call delete('XscrollEvent') +endfunc + +func Test_WinClosed() + " Test that the pattern is matched against the closed window's ID, and both + " <amatch> and <afile> are set to it. + new + let winid = win_getid() + let g:matched = v:false + augroup test-WinClosed + autocmd! + execute 'autocmd WinClosed' winid 'let g:matched = v:true' + autocmd WinClosed * let g:amatch = str2nr(expand('<amatch>')) + autocmd WinClosed * let g:afile = str2nr(expand('<afile>')) + augroup END + close + call assert_true(g:matched) + call assert_equal(winid, g:amatch) + call assert_equal(winid, g:afile) + + " Test that WinClosed is non-recursive. + new + new + call assert_equal(3, winnr('$')) + let g:triggered = 0 + augroup test-WinClosed + autocmd! + autocmd WinClosed * let g:triggered += 1 + autocmd WinClosed * 2 wincmd c + augroup END + close + call assert_equal(1, winnr('$')) + call assert_equal(1, g:triggered) + + autocmd! test-WinClosed + augroup! test-WinClosed + unlet g:matched + unlet g:amatch + unlet g:afile + unlet g:triggered +endfunc + +func Test_WinClosed_throws() + vnew + let bnr = bufnr() + call assert_equal(1, bufloaded(bnr)) + augroup test-WinClosed + autocmd WinClosed * throw 'foo' + augroup END + try + close + catch /.*/ + endtry + call assert_equal(0, bufloaded(bnr)) + + autocmd! test-WinClosed + augroup! test-WinClosed +endfunc + +func Test_WinClosed_throws_with_tabs() + tabnew + let bnr = bufnr() + call assert_equal(1, bufloaded(bnr)) + augroup test-WinClosed + autocmd WinClosed * throw 'foo' + augroup END + try + close + catch /.*/ + endtry + call assert_equal(0, bufloaded(bnr)) + + autocmd! test-WinClosed + augroup! test-WinClosed +endfunc + +" This used to trigger WinClosed twice for the same window, and the window's +" buffer was NULL in the second autocommand. +func Test_WinClosed_switch_tab() + edit Xa + split Xb + split Xc + tab split + new + augroup test-WinClosed + autocmd WinClosed * tabprev | bwipe! + augroup END + close + " Check that the tabline has been fully removed + call assert_equal([1, 1], win_screenpos(0)) + + autocmd! test-WinClosed + augroup! test-WinClosed + %bwipe! +endfunc + +func s:AddAnAutocmd() + augroup vimBarTest + au BufReadCmd * echo 'hello' + augroup END + call assert_equal(3, len(split(execute('au vimBarTest'), "\n"))) +endfunc + +func Test_early_bar() + " test that a bar is recognized before the {event} + call s:AddAnAutocmd() + augroup vimBarTest | au! | let done = 77 | augroup END + call assert_equal(1, len(split(execute('au vimBarTest'), "\n"))) + call assert_equal(77, done) + + call s:AddAnAutocmd() + augroup vimBarTest| au!| let done = 88 | augroup END + call assert_equal(1, len(split(execute('au vimBarTest'), "\n"))) + call assert_equal(88, done) + + " test that a bar is recognized after the {event} + call s:AddAnAutocmd() + augroup vimBarTest| au!BufReadCmd| let done = 99 | augroup END + call assert_equal(1, len(split(execute('au vimBarTest'), "\n"))) + call assert_equal(99, done) + + " test that a bar is recognized after the {group} + call s:AddAnAutocmd() + au! vimBarTest|echo 'hello' + call assert_equal(1, len(split(execute('au vimBarTest'), "\n"))) +endfunc + +func RemoveGroup() + autocmd! StartOK + augroup! StartOK +endfunc + +func Test_augroup_warning() + augroup TheWarning + au VimEnter * echo 'entering' + augroup END + call assert_match("TheWarning.*VimEnter", execute('au VimEnter')) + redir => res + augroup! TheWarning + redir END + call assert_match("W19:", res) + call assert_match("-Deleted-.*VimEnter", execute('au VimEnter')) + + " check "Another" does not take the pace of the deleted entry + augroup Another + augroup END + call assert_match("-Deleted-.*VimEnter", execute('au VimEnter')) + augroup! Another + + " no warning for postpone aucmd delete + augroup StartOK + au VimEnter * call RemoveGroup() + augroup END + call assert_match("StartOK.*VimEnter", execute('au VimEnter')) + redir => res + doautocmd VimEnter + redir END + call assert_notmatch("W19:", res) + au! VimEnter + + call assert_fails('augroup!', 'E471:') +endfunc + +func Test_BufReadCmdHelp() + " This used to cause access to free memory + au BufReadCmd * e +h + help + + au! BufReadCmd +endfunc + +func Test_BufReadCmdHelpJump() + " This used to cause access to free memory + au BufReadCmd * e +h{ + " } to fix highlighting + call assert_fails('help', 'E434:') + + au! BufReadCmd +endfunc + +" BufReadCmd is triggered for a "nofile" buffer. Check all values. +func Test_BufReadCmdNofile() + for val in ['nofile', + \ 'nowrite', + \ 'acwrite', + \ 'quickfix', + \ 'help', + "\ 'terminal', + \ 'prompt', + "\ 'popup', + \ ] + new somefile + exe 'set buftype=' .. val + au BufReadCmd somefile call setline(1, 'triggered') + edit + call assert_equal('triggered', getline(1)) + + au! BufReadCmd + bwipe! + endfor +endfunc + +func Test_augroup_deleted() + " This caused a crash before E936 was introduced + augroup x + call assert_fails('augroup! x', 'E936:') + au VimEnter * echo + augroup end + augroup! x + call assert_match("-Deleted-.*VimEnter", execute('au VimEnter')) + au! VimEnter +endfunc + +" Tests for autocommands on :close command. +" This used to be in test13. +func Test_three_windows() + " Clean up buffers, because in some cases this function fails. + call s:cleanup_buffers() + + " Write three files and open them, each in a window. + " Then go to next window, with autocommand that deletes the previous one. + " Do this twice, writing the file. + e! Xtestje1 + call setline(1, 'testje1') + w + sp Xtestje2 + call setline(1, 'testje2') + w + sp Xtestje3 + call setline(1, 'testje3') + w + wincmd w + au WinLeave Xtestje2 bwipe + wincmd w + call assert_equal('Xtestje1', expand('%')) + + au WinLeave Xtestje1 bwipe Xtestje3 + close + call assert_equal('Xtestje1', expand('%')) + + " Test deleting the buffer on a Unload event. If this goes wrong there + " will be the ATTENTION prompt. + e Xtestje1 + au! + au! BufUnload Xtestje1 bwipe + call assert_fails('e Xtestje3', 'E937:') + call assert_equal('Xtestje3', expand('%')) + + e Xtestje2 + sp Xtestje1 + call assert_fails('e', 'E937:') + call assert_equal('Xtestje1', expand('%')) + + " Test changing buffers in a BufWipeout autocommand. If this goes wrong + " there are ml_line errors and/or a Crash. + au! + only + e Xanother + e Xtestje1 + bwipe Xtestje2 + bwipe Xtestje3 + au BufWipeout Xtestje1 buf Xtestje1 + bwipe + call assert_equal('Xanother', expand('%')) + + only + + help + wincmd w + 1quit + call assert_equal('Xanother', expand('%')) + + au! + enew + call delete('Xtestje1') + call delete('Xtestje2') + call delete('Xtestje3') +endfunc + +func Test_BufEnter() + au! BufEnter + au Bufenter * let val = val . '+' + let g:val = '' + split NewFile + call assert_equal('+', g:val) + bwipe! + call assert_equal('++', g:val) + + " Also get BufEnter when editing a directory + call mkdir('Xbufenterdir', 'D') + split Xbufenterdir + call assert_equal('+++', g:val) + + " On MS-Windows we can't edit the directory, make sure we wipe the right + " buffer. + bwipe! Xbufenterdir + au! BufEnter + + " Editing a "nofile" buffer doesn't read the file but does trigger BufEnter + " for historic reasons. Also test other 'buftype' values. + for val in ['nofile', + \ 'nowrite', + \ 'acwrite', + \ 'quickfix', + \ 'help', + "\ 'terminal', + \ 'prompt', + "\ 'popup', + \ ] + new somefile + exe 'set buftype=' .. val + au BufEnter somefile call setline(1, 'some text') + edit + call assert_equal('some text', getline(1)) + bwipe! + au! BufEnter + endfor +endfunc + +" Closing a window might cause an endless loop +" E814 for older Vims +func Test_autocmd_bufwipe_in_SessLoadPost() + edit Xtest + tabnew + file Xsomething + set noswapfile + mksession! + + let content =<< trim [CODE] + set nocp noswapfile + let v:swapchoice = "e" + augroup test_autocmd_sessionload + autocmd! + autocmd SessionLoadPost * exe bufnr("Xsomething") . "bw!" + augroup END + + func WriteErrors() + call writefile([execute("messages")], "XerrorsBwipe") + endfunc + au VimLeave * call WriteErrors() + [CODE] + + call writefile(content, 'Xvimrc', 'D') + call system(GetVimCommand('Xvimrc') .. ' --headless --noplugins -S Session.vim -c cq') + sleep 100m + let errors = join(readfile('XerrorsBwipe')) + call assert_match('E814:', errors) + + set swapfile + for file in ['Session.vim', 'XerrorsBwipe'] + call delete(file) + endfor +endfunc + +" Using :blast and :ball for many events caused a crash, because b_nwindows was +" not incremented correctly. +func Test_autocmd_blast_badd() + let content =<< trim [CODE] + au BufNew,BufAdd,BufWinEnter,BufEnter,BufLeave,BufWinLeave,BufUnload,VimEnter foo* blast + edit foo1 + au BufNew,BufAdd,BufWinEnter,BufEnter,BufLeave,BufWinLeave,BufUnload,VimEnter foo* ball + edit foo2 + call writefile(['OK'], 'XerrorsBlast') + qall + [CODE] + + call writefile(content, 'XblastBall', 'D') + call system(GetVimCommand() .. ' --clean -S XblastBall') + sleep 100m + call assert_match('OK', readfile('XerrorsBlast')->join()) + + call delete('XerrorsBlast') +endfunc + +" SEGV occurs in older versions. +func Test_autocmd_bufwipe_in_SessLoadPost2() + tabnew + set noswapfile + mksession! + + let content =<< trim [CODE] + set nocp noswapfile + function! DeleteInactiveBufs() + tabfirst + let tabblist = [] + for i in range(1, tabpagenr(''$'')) + call extend(tabblist, tabpagebuflist(i)) + endfor + for b in range(1, bufnr(''$'')) + if bufexists(b) && buflisted(b) && (index(tabblist, b) == -1 || bufname(b) =~# ''^$'') + exec ''bwipeout '' . b + endif + endfor + echomsg "SessionLoadPost DONE" + endfunction + au SessionLoadPost * call DeleteInactiveBufs() + + func WriteErrors() + call writefile([execute("messages")], "XerrorsPost") + endfunc + au VimLeave * call WriteErrors() + [CODE] + + call writefile(content, 'Xvimrc', 'D') + call system(GetVimCommand('Xvimrc') .. ' --headless --noplugins -S Session.vim -c cq') + sleep 100m + let errors = join(readfile('XerrorsPost')) + " This probably only ever matches on unix. + call assert_notmatch('Caught deadly signal SEGV', errors) + call assert_match('SessionLoadPost DONE', errors) + + set swapfile + for file in ['Session.vim', 'XerrorsPost'] + call delete(file) + endfor +endfunc + +func Test_empty_doau() + doau \| +endfunc + +func s:AutoCommandOptionSet(match) + let template = "Option: <%s>, OldVal: <%s>, OldValLocal: <%s>, OldValGlobal: <%s>, NewVal: <%s>, Scope: <%s>, Command: <%s>\n" + let item = remove(g:options, 0) + let expected = printf(template, item[0], item[1], item[2], item[3], item[4], item[5], item[6]) + let actual = printf(template, a:match, v:option_old, v:option_oldlocal, v:option_oldglobal, v:option_new, v:option_type, v:option_command) + let g:opt = [expected, actual] + "call assert_equal(expected, actual) +endfunc + +func Test_OptionSet() + CheckFunction test_override + CheckOption autochdir + + call test_override('starting', 1) + set nocp + au OptionSet * :call s:AutoCommandOptionSet(expand("<amatch>")) + + " 1: Setting number option" + let g:options = [['number', 0, 0, 0, 1, 'global', 'set']] + set nu + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 2: Setting local number option" + let g:options = [['number', 1, 1, '', 0, 'local', 'setlocal']] + setlocal nonu + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 3: Setting global number option" + let g:options = [['number', 1, '', 1, 0, 'global', 'setglobal']] + setglobal nonu + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 4: Setting local autoindent option" + let g:options = [['autoindent', 0, 0, '', 1, 'local', 'setlocal']] + setlocal ai + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 5: Setting global autoindent option" + let g:options = [['autoindent', 0, '', 0, 1, 'global', 'setglobal']] + setglobal ai + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 6: Setting global autoindent option" + let g:options = [['autoindent', 1, 1, 1, 0, 'global', 'set']] + set ai! + call assert_equal([], g:options) + call assert_equal(g:opt[0], g:opt[1]) + + " 6a: Setting global autoindent option" + let g:options = [['autoindent', 1, 1, 0, 0, 'global', 'set']] + noa setlocal ai + noa setglobal noai + set ai! + call assert_equal([], g:options) + call assert_equal(g: |