To: vim-dev@vim.org Subject: Patch 6.2.472 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.2.472 Problem: When using a FileChangedShell autocommand that changes the current buffer, a buffer exists that can't be wiped out. Also, Vim sometimes crashes when executing an external command that changes the buffer and a FileChangedShell autocommand is used. (Hari Krishna Dara) Users are confused by the warning for a file being changed outside of Vim. Solution: Avoid that the window counter for a buffer is incremented twice. Avoid that buf_check_timestamp() is used recursively. Add a hint to look in the help for more info. Files: src/ex_cmds.c, src/fileio.c *** ../vim-6.2.471/src/ex_cmds.c Mon Apr 5 22:14:07 2004 --- src/ex_cmds.c Tue Apr 13 19:33:07 2004 *************** *** 2711,2718 **** { oldbuf = TRUE; (void)buf_check_timestamp(buf, FALSE); ! /* Check if autocommands made buffer invalid. */ ! if (!buf_valid(buf)) goto theend; #ifdef FEAT_EVAL if (aborting()) /* autocmds may abort script processing */ --- 2711,2723 ---- { oldbuf = TRUE; (void)buf_check_timestamp(buf, FALSE); ! /* Check if autocommands made buffer invalid or changed the current ! * buffer. */ ! if (!buf_valid(buf) ! #ifdef FEAT_AUTOCMD ! || curbuf != old_curbuf ! #endif ! ) goto theend; #ifdef FEAT_EVAL if (aborting()) /* autocmds may abort script processing */ *** ../vim-6.2.471/src/fileio.c Tue Mar 30 22:17:27 2004 --- src/fileio.c Wed Apr 14 22:34:56 2004 *************** *** 1701,1707 **** ++lnum; if (--read_count == 0) { ! error = TRUE; /* break loop */ line_start = ptr; /* nothing left to write */ break; } --- 1701,1707 ---- ++lnum; if (--read_count == 0) { ! error = TRUE; /* break loop */ line_start = ptr; /* nothing left to write */ break; } *************** *** 5503,5508 **** --- 5503,5510 ---- char_u *path; char_u *tbuf; char *mesg = NULL; + char *mesg2; + int helpmesg = FALSE; int reload = FALSE; #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG) int can_reload = FALSE; *************** *** 5512,5526 **** #ifdef FEAT_GUI int save_mouse_correct = need_mouse_correct; #endif /* If there is no file name, the buffer is not loaded, 'buftype' is ! * set, or we are in the middle of a save: ignore this buffer. */ if (buf->b_ffname == NULL || buf->b_ml.ml_mfp == NULL #if defined(FEAT_QUICKFIX) || *buf->b_p_bt != NUL #endif || buf->b_saving ) return 0; --- 5514,5535 ---- #ifdef FEAT_GUI int save_mouse_correct = need_mouse_correct; #endif + #ifdef FEAT_AUTOCMD + static int busy = FALSE; + #endif /* If there is no file name, the buffer is not loaded, 'buftype' is ! * set, we are in the middle of a save or being called recursively: ignore ! * this buffer. */ if (buf->b_ffname == NULL || buf->b_ml.ml_mfp == NULL #if defined(FEAT_QUICKFIX) || *buf->b_p_bt != NUL #endif || buf->b_saving + #ifdef FEAT_AUTOCMD + || busy + #endif ) return 0; *************** *** 5563,5579 **** else { #ifdef FEAT_AUTOCMD /* * Only give the warning if there are no FileChangedShell * autocommands. */ ! if (apply_autocmds(EVENT_FILECHANGEDSHELL, ! buf->b_fname, buf->b_fname, FALSE, buf)) { if (!buf_valid(buf)) - { EMSG(_("E246: FileChangedShell autocommand deleted buffer")); - } return 2; } else --- 5572,5592 ---- else { #ifdef FEAT_AUTOCMD + int n; + /* * Only give the warning if there are no FileChangedShell * autocommands. + * Avoid being called recursively by setting "busy". */ ! busy = TRUE; ! n = apply_autocmds(EVENT_FILECHANGEDSHELL, ! buf->b_fname, buf->b_fname, FALSE, buf); ! busy = FALSE; ! if (n) { if (!buf_valid(buf)) EMSG(_("E246: FileChangedShell autocommand deleted buffer")); return 2; } else *************** *** 5583,5588 **** --- 5596,5602 ---- mesg = _("E211: Warning: File \"%s\" no longer available"); else { + helpmesg = TRUE; #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG) can_reload = TRUE; #endif *************** *** 5620,5630 **** path = home_replace_save(buf, buf->b_fname); if (path != NULL) { ! tbuf = alloc((unsigned)(STRLEN(path) + STRLEN(mesg))); sprintf((char *)tbuf, mesg, path); #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG) if (can_reload) { if (do_dialog(VIM_WARNING, (char_u *)_("Warning"), tbuf, (char_u *)_("&OK\n&Load File"), 1, NULL) == 2) reload = TRUE; --- 5634,5654 ---- path = home_replace_save(buf, buf->b_fname); if (path != NULL) { ! if (helpmesg) ! mesg2 = _("See \":help W11\" for more info."); ! else ! mesg2 = ""; ! tbuf = alloc((unsigned)(STRLEN(path) + STRLEN(mesg) ! + STRLEN(mesg2) + 2)); sprintf((char *)tbuf, mesg, path); #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG) if (can_reload) { + if (*mesg2 != NUL) + { + STRCAT(tbuf, "\n"); + STRCAT(tbuf, mesg2); + } if (do_dialog(VIM_WARNING, (char_u *)_("Warning"), tbuf, (char_u *)_("&OK\n&Load File"), 1, NULL) == 2) reload = TRUE; *************** *** 5633,5638 **** --- 5657,5667 ---- #endif if (State > NORMAL_BUSY || (State & CMDLINE) || already_warned) { + if (*mesg2 != NUL) + { + STRCAT(tbuf, "; "); + STRCAT(tbuf, mesg2); + } EMSG(tbuf); retval = 2; } *************** *** 5647,5652 **** --- 5676,5684 ---- { msg_start(); msg_puts_attr(tbuf, hl_attr(HLF_E) + MSG_HIST); + if (*mesg2 != NUL) + msg_puts_attr((char_u *)mesg2, + hl_attr(HLF_W) + MSG_HIST); msg_clr_eos(); (void)msg_end(); if (emsg_silent == 0) *** ../vim-6.2.471/src/version.c Wed Apr 14 22:12:42 2004 --- src/version.c Wed Apr 14 22:36:28 2004 *************** *** 639,640 **** --- 639,642 ---- { /* Add new patch number below this line */ + /**/ + 472, /**/ -- ARTHUR: What does it say? BROTHER MAYNARD: It reads ... "Here may be found the last words of Joseph of Aramathea." "He who is valorous and pure of heart may find the Holy Grail in the aaaaarrrrrrggghhh..." ARTHUR: What? BROTHER MAYNARD: "The Aaaaarrrrrrggghhh..." "Monty Python and the Holy Grail" PYTHON (MONTY) PICTURES LTD /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Buy at Amazon and help AIDS victims -- http://ICCF.nl/click1.html ///