Hi Bram and Vim developers,
How to reproduce:
1. Prepare test_vimrc
$ cat test_vimrc
augroup vimrc
autocmd!
augroup END
autocmd vimrc WinEnter * :execute ( (winnr('$') == 1) && (&filetype ==# 'qf')
? 'bwipeout!' : '')
2. Start vim
$ vim -N -u test_vimrc
3. Open quickfix window
:copen
4. Move current window to above one.
<C-W>k
5. Wipe current buffer
:bwipeout
Expect behavior:
Display one window and one unnamed buffer.
Actual behavior:
SEGV
--------
Investigation result:
+----------------+
| win1(buf1) |
| (current) |
+----------------+
| win2(buf2) |
| |
+----------------+
1. win1 closed and move current window to win2 (in bwipe buf1 process)
2. Triggered autocmd(WinEnter) then execute :bwipeout! to buf2
3. Now exist window is win2(current). And exist buf is buf1(current).
4. Search for the next current buffer candidate. (in bwipe buf1 process)
5. Next buffer candidate is NULL !?!? (at buffer.c:1362)
6. Wipe current buffer(buf1) and new current buffer(==NULL) !?!?
7. SEGV
--------
Solution
If next current window candidate is NULL (at buffer.c:1311),
then create new buffer and close buf1. (like buffer.c:1159 ~ 1180)
And don't display file info after redraw.
I attached a patch.
Please check this.
Thanks for reading my crazy english.
Best regards,
Hirohito Higashi
--
--
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/groups/opt_out.
diff -r 2f856c7c1d43 src/buffer.c
--- a/src/buffer.c Sun Dec 15 10:02:33 2013 +0100
+++ b/src/buffer.c Mon Jan 06 01:14:30 2014 +0900
@@ -1309,6 +1309,28 @@
else
buf = curbuf->b_prev;
}
+ if (buf == NULL) /* Still no buffer, just create one */
+ {
+ if (action == DOBUF_UNLOAD)
+ {
+ EMSG(_("E90: Cannot unload last buffer"));
+ return FAIL;
+ }
+
+ buf = curbuf;
+ setpcmark();
+ retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE,
+ forceit ? ECMD_FORCEIT : 0, curwin);
+ /*
+ * do_ecmd() may create a new buffer, then we have to delete
+ * the old one. But do_ecmd() may have done that already, check
+ * if the buffer still exists.
+ */
+ if (buf != curbuf && buf_valid(buf) && buf->b_nwindows == 0)
+ close_buffer(NULL, buf, action, FALSE);
+ need_fileinfo = FALSE; /* Don't display file info after redraw */
+ return retval;
+ }
}
/*