| To: vim_dev@googlegroups.com |
| Subject: Patch 7.4.140 |
| Fcc: outbox |
| From: Bram Moolenaar <Bram@moolenaar.net> |
| Mime-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| |
| Patch 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) |
| Files: src/buffer.c |
| |
| |
| |
| |
| |
| *** 994,999 **** |
| --- 994,1043 ---- |
| #if defined(FEAT_LISTCMDS) || defined(FEAT_PYTHON) \ |
| || 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. |
| * |
| |
| *** 1114,1120 **** |
| if (unload) |
| { |
| int forward; |
| - int retval; |
| |
| /* When unloading or deleting a buffer that's already unloaded and |
| * unlisted: fail silently. */ |
| --- 1158,1163 ---- |
| |
| *** 1155,1184 **** |
| if (bp->b_p_bl && bp != buf) |
| break; |
| if (bp == NULL && buf == curbuf) |
| ! { |
| ! 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 |
| /* |
| --- 1198,1204 ---- |
| if (bp->b_p_bl && bp != buf) |
| break; |
| if (bp == NULL && buf == curbuf) |
| ! return empty_curbuf(TRUE, forceit, action); |
| |
| #ifdef FEAT_WINDOWS |
| /* |
| |
| *** 1212,1218 **** |
| |
| /* |
| * Deleting the current buffer: Need to find another buffer to go to. |
| ! * There must be another, otherwise it would have been handled above. |
| * First use au_new_curbuf, if it is valid. |
| * Then prefer the buffer we most recently visited. |
| * Else try to find one that is loaded, after the current buffer, |
| --- 1232,1239 ---- |
| |
| /* |
| * Deleting the current buffer: Need to find another buffer to go to. |
| ! * 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. |
| * Then prefer the buffer we most recently visited. |
| * Else try to find one that is loaded, after the current buffer, |
| |
| *** 1311,1316 **** |
| --- 1332,1344 ---- |
| } |
| } |
| |
| + 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 |
| */ |
| |
| |
| |
| *** 740,741 **** |
| --- 740,743 ---- |
| { /* Add new patch number below this line */ |
| + /**/ |
| + 140, |
| /**/ |
| |
| -- |
| hundred-and-one symptoms of being an internet addict: |
| 133. You communicate with people on other continents more than you |
| do with your own neighbors. |
| |
| /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ |
| /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ |
| \\\ an exciting new programming language -- http://www.Zimbu.org /// |
| \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |