Mercurial > vim
comparison src/buffer.c @ 18886:050f5eaa9e50 v8.2.0004
patch 8.2.0004: get E685 and E931 if buffer reload is interrupted
Commit: https://github.com/vim/vim/commit/a6e8f888e7fc31b8ab7233509254fb2e2fe4089f
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Dec 14 16:18:15 2019 +0100
patch 8.2.0004: get E685 and E931 if buffer reload is interrupted
Problem: Get E685 and E931 if buffer reload is interrupted.
Solution: Do not abort deleting a dummy buffer. (closes https://github.com/vim/vim/issues/5361)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 14 Dec 2019 16:30:04 +0100 |
parents | 9449ed2ee8d4 |
children | 5c405689da3e |
comparison
equal
deleted
inserted
replaced
18885:f4852c310de1 | 18886:050f5eaa9e50 |
---|---|
182 { | 182 { |
183 /* | 183 /* |
184 * There MUST be a memfile, otherwise we can't do anything | 184 * There MUST be a memfile, otherwise we can't do anything |
185 * If we can't create one for the current buffer, take another buffer | 185 * If we can't create one for the current buffer, take another buffer |
186 */ | 186 */ |
187 close_buffer(NULL, curbuf, 0, FALSE); | 187 close_buffer(NULL, curbuf, 0, FALSE, FALSE); |
188 FOR_ALL_BUFFERS(curbuf) | 188 FOR_ALL_BUFFERS(curbuf) |
189 if (curbuf->b_ml.ml_mfp != NULL) | 189 if (curbuf->b_ml.ml_mfp != NULL) |
190 break; | 190 break; |
191 /* | 191 /* |
192 * If there is no memfile at all, exit. | 192 * If there is no memfile at all, exit. |
485 * The 'bufhidden' option can force freeing and deleting. | 485 * The 'bufhidden' option can force freeing and deleting. |
486 * | 486 * |
487 * When "abort_if_last" is TRUE then do not close the buffer if autocommands | 487 * When "abort_if_last" is TRUE then do not close the buffer if autocommands |
488 * cause there to be only one window with this buffer. e.g. when ":quit" is | 488 * cause there to be only one window with this buffer. e.g. when ":quit" is |
489 * supposed to close the window but autocommands close all other windows. | 489 * supposed to close the window but autocommands close all other windows. |
490 * | |
491 * When "ignore_abort" is TRUE don't abort even when aborting() returns TRUE. | |
490 */ | 492 */ |
491 void | 493 void |
492 close_buffer( | 494 close_buffer( |
493 win_T *win, // if not NULL, set b_last_cursor | 495 win_T *win, // if not NULL, set b_last_cursor |
494 buf_T *buf, | 496 buf_T *buf, |
495 int action, | 497 int action, |
496 int abort_if_last) | 498 int abort_if_last, |
499 int ignore_abort) | |
497 { | 500 { |
498 int is_curbuf; | 501 int is_curbuf; |
499 int nwindows; | 502 int nwindows; |
500 bufref_T bufref; | 503 bufref_T bufref; |
501 int is_curwin = (curwin != NULL && curwin->w_buffer == buf); | 504 int is_curwin = (curwin != NULL && curwin->w_buffer == buf); |
607 if (abort_if_last && one_window()) | 610 if (abort_if_last && one_window()) |
608 // Autocommands made this the only window. | 611 // Autocommands made this the only window. |
609 goto aucmd_abort; | 612 goto aucmd_abort; |
610 } | 613 } |
611 #ifdef FEAT_EVAL | 614 #ifdef FEAT_EVAL |
612 if (aborting()) // autocmds may abort script processing | 615 // autocmds may abort script processing |
616 if (!ignore_abort && aborting()) | |
613 return; | 617 return; |
614 #endif | 618 #endif |
615 } | 619 } |
616 | 620 |
617 // If the buffer was in curwin and the window has changed, go back to that | 621 // If the buffer was in curwin and the window has changed, go back to that |
660 // Remember if we are closing the current buffer. Restore the number of | 664 // Remember if we are closing the current buffer. Restore the number of |
661 // windows, so that autocommands in buf_freeall() don't get confused. | 665 // windows, so that autocommands in buf_freeall() don't get confused. |
662 is_curbuf = (buf == curbuf); | 666 is_curbuf = (buf == curbuf); |
663 buf->b_nwindows = nwindows; | 667 buf->b_nwindows = nwindows; |
664 | 668 |
665 buf_freeall(buf, (del_buf ? BFA_DEL : 0) + (wipe_buf ? BFA_WIPE : 0)); | 669 buf_freeall(buf, (del_buf ? BFA_DEL : 0) |
670 + (wipe_buf ? BFA_WIPE : 0) | |
671 + (ignore_abort ? BFA_IGNORE_ABORT : 0)); | |
666 | 672 |
667 // Autocommands may have deleted the buffer. | 673 // Autocommands may have deleted the buffer. |
668 if (!bufref_valid(&bufref)) | 674 if (!bufref_valid(&bufref)) |
669 return; | 675 return; |
670 #ifdef FEAT_EVAL | 676 #ifdef FEAT_EVAL |
671 if (aborting()) // autocmds may abort script processing | 677 // autocmds may abort script processing |
678 if (!ignore_abort && aborting()) | |
672 return; | 679 return; |
673 #endif | 680 #endif |
674 | 681 |
675 /* | 682 /* |
676 * It's possible that autocommands change curbuf to the one being deleted. | 683 * It's possible that autocommands change curbuf to the one being deleted. |
760 | 767 |
761 /* | 768 /* |
762 * buf_freeall() - free all things allocated for a buffer that are related to | 769 * buf_freeall() - free all things allocated for a buffer that are related to |
763 * the file. Careful: get here with "curwin" NULL when exiting. | 770 * the file. Careful: get here with "curwin" NULL when exiting. |
764 * flags: | 771 * flags: |
765 * BFA_DEL buffer is going to be deleted | 772 * BFA_DEL buffer is going to be deleted |
766 * BFA_WIPE buffer is going to be wiped out | 773 * BFA_WIPE buffer is going to be wiped out |
767 * BFA_KEEP_UNDO do not free undo information | 774 * BFA_KEEP_UNDO do not free undo information |
775 * BFA_IGNORE_ABORT don't abort even when aborting() returns TRUE | |
768 */ | 776 */ |
769 void | 777 void |
770 buf_freeall(buf_T *buf, int flags) | 778 buf_freeall(buf_T *buf, int flags) |
771 { | 779 { |
772 int is_curbuf = (buf == curbuf); | 780 int is_curbuf = (buf == curbuf); |
813 goto_tabpage_win(the_curtab, the_curwin); | 821 goto_tabpage_win(the_curtab, the_curwin); |
814 unblock_autocmds(); | 822 unblock_autocmds(); |
815 } | 823 } |
816 | 824 |
817 #ifdef FEAT_EVAL | 825 #ifdef FEAT_EVAL |
818 if (aborting()) // autocmds may abort script processing | 826 // autocmds may abort script processing |
827 if ((flags & BFA_IGNORE_ABORT) == 0 && aborting()) | |
819 return; | 828 return; |
820 #endif | 829 #endif |
821 | 830 |
822 /* | 831 /* |
823 * It's possible that autocommands change curbuf to the one being deleted. | 832 * It's possible that autocommands change curbuf to the one being deleted. |
1075 // User selected Quit at ATTENTION prompt. Go back to previous | 1084 // User selected Quit at ATTENTION prompt. Go back to previous |
1076 // buffer. If that buffer is gone or the same as the current one, | 1085 // buffer. If that buffer is gone or the same as the current one, |
1077 // open a new, empty buffer. | 1086 // open a new, empty buffer. |
1078 swap_exists_action = SEA_NONE; // don't want it again | 1087 swap_exists_action = SEA_NONE; // don't want it again |
1079 swap_exists_did_quit = TRUE; | 1088 swap_exists_did_quit = TRUE; |
1080 close_buffer(curwin, curbuf, DOBUF_UNLOAD, FALSE); | 1089 close_buffer(curwin, curbuf, DOBUF_UNLOAD, FALSE, FALSE); |
1081 if (old_curbuf == NULL || !bufref_valid(old_curbuf) | 1090 if (old_curbuf == NULL || !bufref_valid(old_curbuf) |
1082 || old_curbuf->br_buf == curbuf) | 1091 || old_curbuf->br_buf == curbuf) |
1083 buf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED); | 1092 buf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED); |
1084 else | 1093 else |
1085 buf = old_curbuf->br_buf; | 1094 buf = old_curbuf->br_buf; |
1279 * do_ecmd() may create a new buffer, then we have to delete | 1288 * do_ecmd() may create a new buffer, then we have to delete |
1280 * the old one. But do_ecmd() may have done that already, check | 1289 * the old one. But do_ecmd() may have done that already, check |
1281 * if the buffer still exists. | 1290 * if the buffer still exists. |
1282 */ | 1291 */ |
1283 if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows == 0) | 1292 if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows == 0) |
1284 close_buffer(NULL, buf, action, FALSE); | 1293 close_buffer(NULL, buf, action, FALSE, FALSE); |
1285 if (!close_others) | 1294 if (!close_others) |
1286 need_fileinfo = FALSE; | 1295 need_fileinfo = FALSE; |
1287 return retval; | 1296 return retval; |
1288 } | 1297 } |
1289 | 1298 |
1476 */ | 1485 */ |
1477 if (buf != curbuf) | 1486 if (buf != curbuf) |
1478 { | 1487 { |
1479 close_windows(buf, FALSE); | 1488 close_windows(buf, FALSE); |
1480 if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows <= 0) | 1489 if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows <= 0) |
1481 close_buffer(NULL, buf, action, FALSE); | 1490 close_buffer(NULL, buf, action, FALSE, FALSE); |
1482 return OK; | 1491 return OK; |
1483 } | 1492 } |
1484 | 1493 |
1485 /* | 1494 /* |
1486 * Deleting the current buffer: Need to find another buffer to go to. | 1495 * Deleting the current buffer: Need to find another buffer to go to. |
1706 if (prevbuf == curbuf) | 1715 if (prevbuf == curbuf) |
1707 u_sync(FALSE); | 1716 u_sync(FALSE); |
1708 close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL, prevbuf, | 1717 close_buffer(prevbuf == curwin->w_buffer ? curwin : NULL, prevbuf, |
1709 unload ? action : (action == DOBUF_GOTO | 1718 unload ? action : (action == DOBUF_GOTO |
1710 && !buf_hide(prevbuf) | 1719 && !buf_hide(prevbuf) |
1711 && !bufIsChanged(prevbuf)) ? DOBUF_UNLOAD : 0, FALSE); | 1720 && !bufIsChanged(prevbuf)) ? DOBUF_UNLOAD : 0, |
1721 FALSE, FALSE); | |
1712 if (curwin != previouswin && win_valid(previouswin)) | 1722 if (curwin != previouswin && win_valid(previouswin)) |
1713 // autocommands changed curwin, Grr! | 1723 // autocommands changed curwin, Grr! |
1714 curwin = previouswin; | 1724 curwin = previouswin; |
1715 } | 1725 } |
1716 } | 1726 } |
3294 emsg(_("E95: Buffer with this name already exists")); | 3304 emsg(_("E95: Buffer with this name already exists")); |
3295 vim_free(ffname); | 3305 vim_free(ffname); |
3296 return FAIL; | 3306 return FAIL; |
3297 } | 3307 } |
3298 // delete from the list | 3308 // delete from the list |
3299 close_buffer(NULL, obuf, DOBUF_WIPE, FALSE); | 3309 close_buffer(NULL, obuf, DOBUF_WIPE, FALSE, FALSE); |
3300 } | 3310 } |
3301 sfname = vim_strsave(sfname); | 3311 sfname = vim_strsave(sfname); |
3302 if (ffname == NULL || sfname == NULL) | 3312 if (ffname == NULL || sfname == NULL) |
3303 { | 3313 { |
3304 vim_free(sfname); | 3314 vim_free(sfname); |
5631 * marks. | 5641 * marks. |
5632 */ | 5642 */ |
5633 void | 5643 void |
5634 wipe_buffer( | 5644 wipe_buffer( |
5635 buf_T *buf, | 5645 buf_T *buf, |
5636 int aucmd UNUSED) // When TRUE trigger autocommands. | 5646 int aucmd) // When TRUE trigger autocommands. |
5637 { | 5647 { |
5638 if (buf->b_fnum == top_file_num - 1) | 5648 if (buf->b_fnum == top_file_num - 1) |
5639 --top_file_num; | 5649 --top_file_num; |
5640 | 5650 |
5641 if (!aucmd) // Don't trigger BufDelete autocommands here. | 5651 if (!aucmd) // Don't trigger BufDelete autocommands here. |
5642 block_autocmds(); | 5652 block_autocmds(); |
5643 | 5653 |
5644 close_buffer(NULL, buf, DOBUF_WIPE, FALSE); | 5654 close_buffer(NULL, buf, DOBUF_WIPE, FALSE, TRUE); |
5645 | 5655 |
5646 if (!aucmd) | 5656 if (!aucmd) |
5647 unblock_autocmds(); | 5657 unblock_autocmds(); |
5648 } | 5658 } |