Hi Bram and Vimmers,
BufUnload event triggered twice, When :bunload with `bufhidden` set to `unload`
or `delete`.
How to reproduce:
$ cat sample1.vim
new
set bufhidden=unload
augroup mygroup
autocmd!
autocmd BufUnload <buffer> echo 'BufUnload'
autocmd BufDelete <buffer> echo 'BufDelete'
autocmd BufWipeout <buffer> echo 'BufWipeout'
augroup END
bunload
$ vim -Nu NONE -S sample1.vim
Expected behavior:
Following echoes displayed.
BufUnload
BufDelete
Actual behavior:
Following echoes displayed.
BufUnload
BufDelete
BufUnload <--- BufUnload triggered twice!!
I wrote a patch and test.
Please include attached one.
--
Best regards,
Hirohito Higashi (a.k.a. h_east)
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/buffer.c b/src/buffer.c
index 9bc24bc..170e214 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -574,9 +574,12 @@ buf_freeall(buf_T *buf, int flags)
int is_curbuf = (buf == curbuf);
buf->b_closing = TRUE;
- apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf);
- if (!buf_valid(buf)) /* autocommands may delete the buffer */
- return;
+ if (buf->b_ml.ml_mfp != NULL)
+ {
+ apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf);
+ if (!buf_valid(buf)) /* autocommands may delete the buffer */
+ return;
+ }
if ((flags & BFA_DEL) && buf->b_p_bl)
{
apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname, FALSE, buf);
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index d3e0981..1dceb70 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -7,29 +7,56 @@ func Test_vim_did_enter()
" becomes one.
endfunc
-if !has('timers')
- finish
+if has('timers')
+ func ExitInsertMode(id)
+ call feedkeys("\<Esc>")
+ endfunc
+
+ func Test_cursorhold_insert()
+ let g:triggered = 0
+ au CursorHoldI * let g:triggered += 1
+ set updatetime=20
+ call timer_start(100, 'ExitInsertMode')
+ call feedkeys('a', 'x!')
+ call assert_equal(1, g:triggered)
+ endfunc
+
+ func Test_cursorhold_insert_ctrl_x()
+ let g:triggered = 0
+ au CursorHoldI * let g:triggered += 1
+ set updatetime=20
+ call timer_start(100, 'ExitInsertMode')
+ " CursorHoldI does not trigger after CTRL-X
+ call feedkeys("a\<C-X>", 'x!')
+ call assert_equal(0, g:triggered)
+ endfunc
endif
-func ExitInsertMode(id)
- call feedkeys("\<Esc>")
-endfunc
+function 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
-func Test_cursorhold_insert()
- let g:triggered = 0
- au CursorHoldI * let g:triggered += 1
- set updatetime=20
- call timer_start(100, 'ExitInsertMode')
- call feedkeys('a', 'x!')
- call assert_equal(1, g:triggered)
-endfunc
+ 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)
-func Test_cursorhold_insert_ctrl_x()
- let g:triggered = 0
- au CursorHoldI * let g:triggered += 1
- set updatetime=20
- call timer_start(100, 'ExitInsertMode')
- " CursorHoldI does not trigger after CTRL-X
- call feedkeys("a\<C-X>", 'x!')
- call assert_equal(0, g:triggered)
+ augroup! test_bufunload_group
endfunc