mirror of
https://github.com/vim/vim.git
synced 2025-09-25 03:54:15 -04:00
updated for version 7.4.140
Problem: Crash when wiping out buffer triggers autocommand that wipes out only other buffer. Solution: Do not delete the last buffer, make it empty. (Hirohito Higashi)
This commit is contained in:
80
src/buffer.c
80
src/buffer.c
@@ -994,6 +994,50 @@ do_bufdel(command, arg, addr_count, start_bnr, end_bnr, forceit)
|
|||||||
#if defined(FEAT_LISTCMDS) || defined(FEAT_PYTHON) \
|
#if defined(FEAT_LISTCMDS) || defined(FEAT_PYTHON) \
|
||||||
|| defined(FEAT_PYTHON3) || defined(PROTO)
|
|| defined(FEAT_PYTHON3) || defined(PROTO)
|
||||||
|
|
||||||
|
static int empty_curbuf __ARGS((int close_others, int forceit, int action));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make the current buffer empty.
|
||||||
|
* Used when it is wiped out and it's the last buffer.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
empty_curbuf(close_others, forceit, action)
|
||||||
|
int close_others;
|
||||||
|
int forceit;
|
||||||
|
int action;
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
buf_T *buf = curbuf;
|
||||||
|
|
||||||
|
if (action == DOBUF_UNLOAD)
|
||||||
|
{
|
||||||
|
EMSG(_("E90: Cannot unload last buffer"));
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (close_others)
|
||||||
|
{
|
||||||
|
/* Close any other windows on this buffer, then make it empty. */
|
||||||
|
#ifdef FEAT_WINDOWS
|
||||||
|
close_windows(buf, TRUE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (!close_others)
|
||||||
|
need_fileinfo = FALSE;
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Implementation of the commands for the buffer list.
|
* Implementation of the commands for the buffer list.
|
||||||
*
|
*
|
||||||
@@ -1114,7 +1158,6 @@ do_buffer(action, start, dir, count, forceit)
|
|||||||
if (unload)
|
if (unload)
|
||||||
{
|
{
|
||||||
int forward;
|
int forward;
|
||||||
int retval;
|
|
||||||
|
|
||||||
/* When unloading or deleting a buffer that's already unloaded and
|
/* When unloading or deleting a buffer that's already unloaded and
|
||||||
* unlisted: fail silently. */
|
* unlisted: fail silently. */
|
||||||
@@ -1155,30 +1198,7 @@ do_buffer(action, start, dir, count, forceit)
|
|||||||
if (bp->b_p_bl && bp != buf)
|
if (bp->b_p_bl && bp != buf)
|
||||||
break;
|
break;
|
||||||
if (bp == NULL && buf == curbuf)
|
if (bp == NULL && buf == curbuf)
|
||||||
{
|
return empty_curbuf(TRUE, forceit, action);
|
||||||
if (action == DOBUF_UNLOAD)
|
|
||||||
{
|
|
||||||
EMSG(_("E90: Cannot unload last buffer"));
|
|
||||||
return FAIL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close any other windows on this buffer, then make it empty. */
|
|
||||||
#ifdef FEAT_WINDOWS
|
|
||||||
close_windows(buf, TRUE);
|
|
||||||
#endif
|
|
||||||
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);
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef FEAT_WINDOWS
|
#ifdef FEAT_WINDOWS
|
||||||
/*
|
/*
|
||||||
@@ -1212,7 +1232,8 @@ do_buffer(action, start, dir, count, forceit)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Deleting the current buffer: Need to find another buffer to go to.
|
* Deleting the current buffer: Need to find another buffer to go to.
|
||||||
* There must be another, otherwise it would have been handled above.
|
* There should be another, otherwise it would have been handled
|
||||||
|
* above. However, autocommands may have deleted all buffers.
|
||||||
* First use au_new_curbuf, if it is valid.
|
* First use au_new_curbuf, if it is valid.
|
||||||
* Then prefer the buffer we most recently visited.
|
* Then prefer the buffer we most recently visited.
|
||||||
* Else try to find one that is loaded, after the current buffer,
|
* Else try to find one that is loaded, after the current buffer,
|
||||||
@@ -1311,6 +1332,13 @@ do_buffer(action, start, dir, count, forceit)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (buf == NULL)
|
||||||
|
{
|
||||||
|
/* Autocommands must have wiped out all other buffers. Only option
|
||||||
|
* now is to make the current buffer empty. */
|
||||||
|
return empty_curbuf(FALSE, forceit, action);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* make buf current buffer
|
* make buf current buffer
|
||||||
*/
|
*/
|
||||||
|
@@ -738,6 +738,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
140,
|
||||||
/**/
|
/**/
|
||||||
139,
|
139,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user