# HG changeset patch # User Christian Brabandt # Date 1468181706 -7200 # Node ID 69ed2c9d34a69da40754a2b81c03200d6eb71e89 # Parent b931ed8a6782635dc79b40c30064ac0ccbf1d2cb commit https://github.com/vim/vim/commit/7c0a2f367f2507669560b1a66423155c70d2e75b Author: Bram Moolenaar Date: Sun Jul 10 22:11:16 2016 +0200 patch 7.4.2024 Problem: More buf_valid() calls can be optimized. Solution: Use bufref_valid() instead. diff --git a/src/buffer.c b/src/buffer.c --- a/src/buffer.c +++ b/src/buffer.c @@ -83,7 +83,7 @@ open_buffer( { int retval = OK; #ifdef FEAT_AUTOCMD - buf_T *old_curbuf; + bufref_T old_curbuf; #endif #ifdef FEAT_SYN_HL long old_tw = curbuf->b_p_tw; @@ -129,7 +129,7 @@ open_buffer( #ifdef FEAT_AUTOCMD /* The autocommands in readfile() may change the buffer, but only AFTER * reading the file. */ - old_curbuf = curbuf; + set_bufref(&old_curbuf, curbuf); modified_was_set = FALSE; #endif @@ -284,12 +284,12 @@ open_buffer( * The autocommands may have changed the current buffer. Apply the * modelines to the correct buffer, if it still exists and is loaded. */ - if (buf_valid(old_curbuf) && old_curbuf->b_ml.ml_mfp != NULL) + if (bufref_valid(&old_curbuf) && old_curbuf.br_buf->b_ml.ml_mfp != NULL) { aco_save_T aco; /* Go to the buffer that was opened. */ - aucmd_prepbuf(&aco, old_curbuf); + aucmd_prepbuf(&aco, old_curbuf.br_buf); #endif do_modelines(0); curbuf->b_flags &= ~(BF_CHECK_RO | BF_NEVERLOADED); @@ -809,7 +809,9 @@ goto_buffer( int count) { # if defined(FEAT_WINDOWS) && defined(HAS_SWAP_EXISTS_ACTION) - buf_T *old_curbuf = curbuf; + bufref_T old_curbuf; + + set_bufref(&old_curbuf, curbuf); swap_exists_action = SEA_DIALOG; # endif @@ -838,7 +840,7 @@ goto_buffer( # endif } else - handle_swap_exists(old_curbuf); + handle_swap_exists(&old_curbuf); # endif } #endif @@ -849,7 +851,7 @@ goto_buffer( * It is allowed for "old_curbuf" to be NULL or invalid. */ void -handle_swap_exists(buf_T *old_curbuf) +handle_swap_exists(bufref_T *old_curbuf) { # if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) cleanup_T cs; @@ -857,6 +859,7 @@ handle_swap_exists(buf_T *old_curbuf) #ifdef FEAT_SYN_HL long old_tw = curbuf->b_p_tw; #endif + buf_T *buf; if (swap_exists_action == SEA_QUIT) { @@ -872,11 +875,14 @@ handle_swap_exists(buf_T *old_curbuf) swap_exists_action = SEA_NONE; /* don't want it again */ swap_exists_did_quit = TRUE; close_buffer(curwin, curbuf, DOBUF_UNLOAD, FALSE); - if (!buf_valid(old_curbuf) || old_curbuf == curbuf) - old_curbuf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED); - if (old_curbuf != NULL) + if (old_curbuf == NULL || !bufref_valid(old_curbuf) + || old_curbuf->br_buf == curbuf) + buf = buflist_new(NULL, NULL, 1L, BLN_CURBUF | BLN_LISTED); + else + buf = old_curbuf->br_buf; + if (buf != NULL) { - enter_buffer(old_curbuf); + enter_buffer(buf); #ifdef FEAT_SYN_HL if (old_tw != curbuf->b_p_tw) check_colorcolumn(curwin); diff --git a/src/channel.c b/src/channel.c --- a/src/channel.c +++ b/src/channel.c @@ -362,7 +362,7 @@ channel_still_useful(channel_T *channel) return TRUE; /* If reading from or a buffer it's still useful. */ - if (channel->ch_part[PART_IN].ch_buffer != NULL) + if (channel->ch_part[PART_IN].ch_bufref.br_buf != NULL) return TRUE; /* If there is no callback then nobody can get readahead. If the fd is @@ -379,9 +379,11 @@ channel_still_useful(channel_T *channel) return (channel->ch_callback != NULL && (has_sock_msg || has_out_msg || has_err_msg)) || ((channel->ch_part[PART_OUT].ch_callback != NULL - || channel->ch_part[PART_OUT].ch_buffer) && has_out_msg) + || channel->ch_part[PART_OUT].ch_bufref.br_buf != NULL) + && has_out_msg) || ((channel->ch_part[PART_ERR].ch_callback != NULL - || channel->ch_part[PART_ERR].ch_buffer) && has_err_msg); + || channel->ch_part[PART_ERR].ch_bufref.br_buf != NULL) + && has_err_msg); } /* @@ -1046,19 +1048,19 @@ channel_set_job(channel_T *channel, job_ { chanpart_T *in_part = &channel->ch_part[PART_IN]; - in_part->ch_buffer = job->jv_in_buf; + set_bufref(&in_part->ch_bufref, job->jv_in_buf); ch_logs(channel, "reading from buffer '%s'", - (char *)in_part->ch_buffer->b_ffname); + (char *)in_part->ch_bufref.br_buf->b_ffname); if (options->jo_set & JO_IN_TOP) { if (options->jo_in_top == 0 && !(options->jo_set & JO_IN_BOT)) { /* Special mode: send last-but-one line when appending a line * to the buffer. */ - in_part->ch_buffer->b_write_to_channel = TRUE; + in_part->ch_bufref.br_buf->b_write_to_channel = TRUE; in_part->ch_buf_append = TRUE; in_part->ch_buf_top = - in_part->ch_buffer->b_ml.ml_line_count + 1; + in_part->ch_bufref.br_buf->b_ml.ml_line_count + 1; } else in_part->ch_buf_top = options->jo_in_top; @@ -1068,7 +1070,7 @@ channel_set_job(channel_T *channel, job_ if (options->jo_set & JO_IN_BOT) in_part->ch_buf_bot = options->jo_in_bot; else - in_part->ch_buf_bot = in_part->ch_buffer->b_ml.ml_line_count; + in_part->ch_buf_bot = in_part->ch_bufref.br_buf->b_ml.ml_line_count; } } @@ -1229,7 +1231,7 @@ channel_set_options(channel_T *channel, { ch_logs(channel, "writing out to buffer '%s'", (char *)buf->b_ffname); - channel->ch_part[PART_OUT].ch_buffer = buf; + set_bufref(&channel->ch_part[PART_OUT].ch_bufref, buf); } } } @@ -1244,7 +1246,7 @@ channel_set_options(channel_T *channel, if (!(opt->jo_set & JO_ERR_MODE)) channel->ch_part[PART_ERR].ch_mode = MODE_NL; if (opt->jo_io[PART_ERR] == JIO_OUT) - buf = channel->ch_part[PART_OUT].ch_buffer; + buf = channel->ch_part[PART_OUT].ch_bufref.br_buf; else if (opt->jo_set & JO_ERR_BUF) { buf = buflist_findnr(opt->jo_io_buf[PART_ERR]); @@ -1266,7 +1268,7 @@ channel_set_options(channel_T *channel, { ch_logs(channel, "writing err to buffer '%s'", (char *)buf->b_ffname); - channel->ch_part[PART_ERR].ch_buffer = buf; + set_bufref(&channel->ch_part[PART_ERR].ch_bufref, buf); } } } @@ -1407,15 +1409,15 @@ channel_write_in(channel_T *channel) { chanpart_T *in_part = &channel->ch_part[PART_IN]; linenr_T lnum; - buf_T *buf = in_part->ch_buffer; + buf_T *buf = in_part->ch_bufref.br_buf; int written = 0; if (buf == NULL || in_part->ch_buf_append) return; /* no buffer or using appending */ - if (!buf_valid(buf) || buf->b_ml.ml_mfp == NULL) + if (!bufref_valid(&in_part->ch_bufref) || buf->b_ml.ml_mfp == NULL) { /* buffer was wiped out or unloaded */ - in_part->ch_buffer = NULL; + in_part->ch_bufref.br_buf = NULL; return; } @@ -1437,7 +1439,7 @@ channel_write_in(channel_T *channel) if (lnum > buf->b_ml.ml_line_count) { /* Writing is done, no longer need the buffer. */ - in_part->ch_buffer = NULL; + in_part->ch_bufref.br_buf = NULL; ch_log(channel, "Finished writing all lines to channel"); } else @@ -1459,11 +1461,11 @@ channel_buffer_free(buf_T *buf) { chanpart_T *ch_part = &channel->ch_part[part]; - if (ch_part->ch_buffer == buf) + if (ch_part->ch_bufref.br_buf == buf) { ch_logs(channel, "%s buffer has been wiped out", part_names[part]); - ch_part->ch_buffer = NULL; + ch_part->ch_bufref.br_buf = NULL; } } } @@ -1480,10 +1482,10 @@ channel_write_any_lines(void) { chanpart_T *in_part = &channel->ch_part[PART_IN]; - if (in_part->ch_buffer != NULL) + if (in_part->ch_bufref.br_buf != NULL) { if (in_part->ch_buf_append) - channel_write_new_lines(in_part->ch_buffer); + channel_write_new_lines(in_part->ch_bufref.br_buf); else channel_write_in(channel); } @@ -1507,7 +1509,7 @@ channel_write_new_lines(buf_T *buf) linenr_T lnum; int written = 0; - if (in_part->ch_buffer == buf && in_part->ch_buf_append) + if (in_part->ch_bufref.br_buf == buf && in_part->ch_buf_append) { if (in_part->ch_fd == INVALID_FD) continue; /* pipe was closed */ @@ -2312,7 +2314,7 @@ append_to_buffer(buf_T *buffer, char_u * { chanpart_T *in_part = &ch->ch_part[PART_IN]; - if (in_part->ch_buffer == buffer) + if (in_part->ch_bufref.br_buf == buffer) in_part->ch_buf_bot = buffer->b_ml.ml_line_count; } } @@ -2374,11 +2376,11 @@ may_invoke_callback(channel_T *channel, partial = channel->ch_partial; } - buffer = channel->ch_part[part].ch_buffer; - if (buffer != NULL && !buf_valid(buffer)) + buffer = channel->ch_part[part].ch_bufref.br_buf; + if (buffer != NULL && !bufref_valid(&channel->ch_part[part].ch_bufref)) { /* buffer was wiped out */ - channel->ch_part[part].ch_buffer = NULL; + channel->ch_part[part].ch_bufref.br_buf = NULL; buffer = NULL; } @@ -2834,7 +2836,7 @@ channel_fill_wfds(int maxfd_arg, fd_set { chanpart_T *in_part = &ch->ch_part[PART_IN]; - if (in_part->ch_fd != INVALID_FD && in_part->ch_buffer != NULL) + if (in_part->ch_fd != INVALID_FD && in_part->ch_bufref.br_buf != NULL) { FD_SET((int)in_part->ch_fd, wfds); if ((int)in_part->ch_fd >= maxfd) @@ -2857,7 +2859,7 @@ channel_fill_poll_write(int nfd_in, stru { chanpart_T *in_part = &ch->ch_part[PART_IN]; - if (in_part->ch_fd != INVALID_FD && in_part->ch_buffer != NULL) + if (in_part->ch_fd != INVALID_FD && in_part->ch_bufref.br_buf != NULL) { in_part->ch_poll_idx = nfd; fds[nfd].fd = in_part->ch_fd; @@ -3643,8 +3645,8 @@ channel_poll_check(int ret_in, void *fds { if (in_part->ch_buf_append) { - if (in_part->ch_buffer != NULL) - channel_write_new_lines(in_part->ch_buffer); + if (in_part->ch_bufref.br_buf != NULL) + channel_write_new_lines(in_part->ch_bufref.br_buf); } else channel_write_in(channel); @@ -3721,8 +3723,8 @@ channel_select_check(int ret_in, void *r { if (in_part->ch_buf_append) { - if (in_part->ch_buffer != NULL) - channel_write_new_lines(in_part->ch_buffer); + if (in_part->ch_bufref.br_buf != NULL) + channel_write_new_lines(in_part->ch_bufref.br_buf); } else channel_write_in(channel); diff --git a/src/diff.c b/src/diff.c --- a/src/diff.c +++ b/src/diff.c @@ -1069,8 +1069,9 @@ theend: ex_diffsplit(exarg_T *eap) { win_T *old_curwin = curwin; - buf_T *old_curbuf = curbuf; + bufref_T old_curbuf; + set_bufref(&old_curbuf, curbuf); #ifdef FEAT_GUI need_mouse_correct = TRUE; #endif @@ -1092,10 +1093,10 @@ ex_diffsplit(exarg_T *eap) { diff_win_options(old_curwin, TRUE); - if (buf_valid(old_curbuf)) + if (bufref_valid(&old_curbuf)) /* Move the cursor position to that of the old window. */ curwin->w_cursor.lnum = diff_get_corresponding_line( - old_curbuf, + old_curbuf.br_buf, old_curwin->w_cursor.lnum, curbuf, curwin->w_cursor.lnum); @@ -1557,7 +1558,8 @@ diff_check(win_T *wp, linenr_T lnum) /* Compare all lines. If they are equal the lines were inserted * in some buffers, deleted in others, but not changed. */ for (i = 0; i < DB_COUNT; ++i) - if (i != idx && curtab->tp_diffbuf[i] != NULL && dp->df_count[i] != 0) + if (i != idx && curtab->tp_diffbuf[i] != NULL + && dp->df_count[i] != 0) if (!diff_equal_entry(dp, idx, i)) return -1; } diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -10503,8 +10503,9 @@ f_ch_getbufnr(typval_T *argvars, typval_ part = PART_IN; else part = PART_SOCK; - if (channel->ch_part[part].ch_buffer != NULL) - rettv->vval.v_number = channel->ch_part[part].ch_buffer->b_fnum; + if (channel->ch_part[part].ch_bufref.br_buf != NULL) + rettv->vval.v_number = + channel->ch_part[part].ch_bufref.br_buf->b_fnum; } } diff --git a/src/ex_cmds.c b/src/ex_cmds.c --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -3666,7 +3666,7 @@ do_ecmd( buf_T *buf; bufref_T bufref; #if defined(FEAT_AUTOCMD) || defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) - buf_T *old_curbuf = curbuf; + bufref_T old_curbuf; #endif char_u *free_fname = NULL; #ifdef FEAT_BROWSE @@ -3691,6 +3691,9 @@ do_ecmd( if (eap != NULL) command = eap->do_ecmd_cmd; +#if defined(FEAT_AUTOCMD) || defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) + set_bufref(&old_curbuf, curbuf); +#endif if (fnum != 0) { @@ -3857,7 +3860,7 @@ do_ecmd( /* autocommands may change curwin and curbuf */ if (oldwin != NULL) oldwin = curwin; - old_curbuf = curbuf; + set_bufref(&old_curbuf, curbuf); #endif } if (buf == NULL) @@ -3875,7 +3878,7 @@ do_ecmd( * buffer. */ if (!bufref_valid(&bufref) #ifdef FEAT_AUTOCMD - || curbuf != old_curbuf + || curbuf != old_curbuf.br_buf #endif ) goto theend; @@ -3934,7 +3937,7 @@ do_ecmd( auto_buf = TRUE; else { - if (curbuf == old_curbuf) + if (curbuf == old_curbuf.br_buf) #endif buf_copy_options(buf, BCO_ENTER); @@ -4196,7 +4199,7 @@ do_ecmd( #if defined(HAS_SWAP_EXISTS_ACTION) if (swap_exists_action == SEA_QUIT) retval = FAIL; - handle_swap_exists(old_curbuf); + handle_swap_exists(&old_curbuf); #endif } #ifdef FEAT_AUTOCMD diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -1693,6 +1693,7 @@ prof_def_func(void) autowrite(buf_T *buf, int forceit) { int r; + bufref_T bufref; if (!(p_aw || p_awa) || !p_write #ifdef FEAT_QUICKFIX @@ -1701,11 +1702,12 @@ autowrite(buf_T *buf, int forceit) #endif || (!forceit && buf->b_p_ro) || buf->b_ffname == NULL) return FAIL; + set_bufref(&bufref, buf); r = buf_write_all(buf, forceit); /* Writing may succeed but the buffer still changed, e.g., when there is a * conversion error. We do want to return FAIL then. */ - if (buf_valid(buf) && bufIsChanged(buf)) + if (bufref_valid(&bufref) && bufIsChanged(buf)) r = FAIL; return r; } @@ -1723,10 +1725,15 @@ autowrite_all(void) for (buf = firstbuf; buf; buf = buf->b_next) if (bufIsChanged(buf) && !buf->b_p_ro) { +#ifdef FEAT_AUTOCMD + bufref_T bufref; + + set_bufref(&bufref, buf); +#endif (void)buf_write_all(buf, FALSE); #ifdef FEAT_AUTOCMD /* an autocommand may have deleted the buffer */ - if (!buf_valid(buf)) + if (!bufref_valid(&bufref)) buf = firstbuf; #endif } @@ -1739,7 +1746,12 @@ autowrite_all(void) int check_changed(buf_T *buf, int flags) { - int forceit = (flags & CCGD_FORCEIT); + int forceit = (flags & CCGD_FORCEIT); +#ifdef FEAT_AUTOCMD + bufref_T bufref; + + set_bufref(&bufref, buf); +#endif if ( !forceit && bufIsChanged(buf) @@ -1762,13 +1774,13 @@ check_changed(buf_T *buf, int flags) )) ++count; # ifdef FEAT_AUTOCMD - if (!buf_valid(buf)) + if (!bufref_valid(&bufref)) /* Autocommand deleted buffer, oops! It's not changed now. */ return FALSE; # endif dialog_changed(buf, count > 1); # ifdef FEAT_AUTOCMD - if (!buf_valid(buf)) + if (!bufref_valid(&bufref)) /* Autocommand deleted buffer, oops! It's not changed now. */ return FALSE; # endif @@ -1867,6 +1879,11 @@ dialog_changed( ) && !buf2->b_p_ro) { +#ifdef FEAT_AUTOCMD + bufref_T bufref; + + set_bufref(&bufref, buf2); +#endif #ifdef FEAT_BROWSE /* May get file name, when there is none */ browse_save_fname(buf2); @@ -1877,7 +1894,7 @@ dialog_changed( (void)buf_write_all(buf2, FALSE); #ifdef FEAT_AUTOCMD /* an autocommand may have deleted the buffer */ - if (!buf_valid(buf2)) + if (!bufref_valid(&bufref)) buf2 = firstbuf; #endif } @@ -1983,11 +2000,14 @@ check_changed_any( continue; if ((!hidden || buf->b_nwindows == 0) && bufIsChanged(buf)) { + bufref_T bufref; + + set_bufref(&bufref, buf); /* Try auto-writing the buffer. If this fails but the buffer no * longer exists it's not changed, that's OK. */ if (check_changed(buf, (p_awa ? CCGD_AW : 0) | CCGD_MULTWIN - | CCGD_ALLBUF) && buf_valid(buf)) + | CCGD_ALLBUF) && bufref_valid(&bufref)) break; /* didn't save - still changes */ } } @@ -2030,10 +2050,15 @@ check_changed_any( FOR_ALL_TAB_WINDOWS(tp, wp) if (wp->w_buffer == buf) { +# ifdef FEAT_AUTOCMD + bufref_T bufref; + + set_bufref(&bufref, buf); +# endif goto_tabpage_win(tp, wp); # ifdef FEAT_AUTOCMD /* Paranoia: did autocms wipe out the buffer with changes? */ - if (!buf_valid(buf)) + if (!bufref_valid(&bufref)) { goto theend; } diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -7322,8 +7322,11 @@ ex_win_close( # if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) if ((p_confirm || cmdmod.confirm) && p_write) { + bufref_T bufref; + + set_bufref(&bufref, buf); dialog_changed(buf, FALSE); - if (buf_valid(buf) && bufIsChanged(buf)) + if (bufref_valid(&bufref) && bufIsChanged(buf)) return; need_hide = FALSE; } diff --git a/src/ex_getln.c b/src/ex_getln.c --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -1666,7 +1666,7 @@ getcmdline( case Ctrl__: /* CTRL-_: switch language mode */ if (!p_ari) break; -#ifdef FEAT_FKMAP +# ifdef FEAT_FKMAP if (p_altkeymap) { cmd_fkmap = !cmd_fkmap; @@ -1674,7 +1674,7 @@ getcmdline( ccline.overstrike = FALSE; } else /* Hebrew is default */ -#endif +# endif cmd_hkmap = !cmd_hkmap; goto cmdline_not_changed; #endif @@ -6655,9 +6655,9 @@ cmd_gchar(int offset) ex_window(void) { struct cmdline_info save_ccline; - buf_T *old_curbuf = curbuf; + bufref_T old_curbuf; win_T *old_curwin = curwin; - buf_T *bp; + bufref_T bufref; win_T *wp; int i; linenr_T lnum; @@ -6686,6 +6686,7 @@ ex_window(void) beep_flush(); return K_IGNORE; } + set_bufref(&old_curbuf, curbuf); /* Save current window sizes. */ win_size_save(&winsizes); @@ -6832,7 +6833,7 @@ ex_window(void) /* Safety check: The old window or buffer was deleted: It's a bug when * this happens! */ - if (!win_valid(old_curwin) || !buf_valid(old_curbuf)) + if (!win_valid(old_curwin) || !bufref_valid(&old_curbuf)) { cmdwin_result = Ctrl_C; EMSG(_("E199: Active window or buffer deleted")); @@ -6903,14 +6904,14 @@ ex_window(void) curwin->w_p_cole = 0; # endif wp = curwin; - bp = curbuf; + set_bufref(&bufref, curbuf); win_goto(old_curwin); win_close(wp, TRUE); /* win_close() may have already wiped the buffer when 'bh' is * set to 'wipe' */ - if (buf_valid(bp)) - close_buffer(NULL, bp, DOBUF_WIPE, FALSE); + if (bufref_valid(&bufref)) + close_buffer(NULL, bufref.br_buf, DOBUF_WIPE, FALSE); /* Restore window sizes. */ win_size_restore(&winsizes); diff --git a/src/fileio.c b/src/fileio.c --- a/src/fileio.c +++ b/src/fileio.c @@ -3287,6 +3287,7 @@ buf_write( int did_cmd = FALSE; int nofile_err = FALSE; int empty_memline = (buf->b_ml.ml_mfp == NULL); + bufref_T bufref; /* * Apply PRE autocommands. @@ -3304,6 +3305,7 @@ buf_write( /* set curwin/curbuf to buf and save a few things */ aucmd_prepbuf(&aco, buf); + set_bufref(&bufref, buf); if (append) { @@ -3376,7 +3378,7 @@ buf_write( * 2. The autocommands abort script processing. * 3. If one of the "Cmd" autocommands was executed. */ - if (!buf_valid(buf)) + if (!bufref_valid(&bufref)) buf = NULL; if (buf == NULL || (buf->b_ml.ml_mfp == NULL && !empty_memline) || did_cmd || nofile_err @@ -6675,10 +6677,13 @@ check_timestamps( /* Only check buffers in a window. */ if (buf->b_nwindows > 0) { + bufref_T bufref; + + set_bufref(&bufref, buf); n = buf_check_timestamp(buf, focus); if (didit < n) didit = n; - if (n > 0 && !buf_valid(buf)) + if (n > 0 && !bufref_valid(&bufref)) { /* Autocommands have removed the buffer, start at the * first one again. */ @@ -6766,6 +6771,7 @@ buf_check_timestamp( char *mesg2 = ""; int helpmesg = FALSE; int reload = FALSE; + char *reason; #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG) int can_reload = FALSE; #endif @@ -6778,8 +6784,10 @@ buf_check_timestamp( static int busy = FALSE; int n; char_u *s; -#endif - char *reason; + bufref_T bufref; + + set_bufref(&bufref, buf); +#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 @@ -6868,7 +6876,7 @@ buf_check_timestamp( busy = FALSE; if (n) { - if (!buf_valid(buf)) + if (!bufref_valid(&bufref)) EMSG(_("E246: FileChangedShell autocommand deleted buffer")); # ifdef FEAT_EVAL s = get_vim_var_str(VV_FCS_CHOICE); @@ -7026,7 +7034,7 @@ buf_check_timestamp( #ifdef FEAT_AUTOCMD /* Trigger FileChangedShell when the file was changed in any way. */ - if (buf_valid(buf) && retval != 0) + if (bufref_valid(&bufref) && retval != 0) (void)apply_autocmds(EVENT_FILECHANGEDSHELLPOST, buf->b_fname, buf->b_fname, FALSE, buf); #endif @@ -7053,6 +7061,7 @@ buf_reload(buf_T *buf, int orig_mode) linenr_T old_topline; int old_ro = buf->b_p_ro; buf_T *savebuf; + bufref_T bufref; int saved = OK; aco_save_T aco; int flags = READ_NEW; @@ -7090,6 +7099,7 @@ buf_reload(buf_T *buf, int orig_mode) { /* Allocate a buffer without putting it in the buffer list. */ savebuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY); + set_bufref(&bufref, savebuf); if (savebuf != NULL && buf == curbuf) { /* Open the memline. */ @@ -7122,7 +7132,7 @@ buf_reload(buf_T *buf, int orig_mode) if (!aborting()) #endif EMSG2(_("E321: Could not reload \"%s\""), buf->b_fname); - if (savebuf != NULL && buf_valid(savebuf) && buf == curbuf) + if (savebuf != NULL && bufref_valid(&bufref) && buf == curbuf) { /* Put the text back from the save buffer. First * delete any lines that readfile() added. */ @@ -7150,7 +7160,7 @@ buf_reload(buf_T *buf, int orig_mode) } vim_free(ea.cmd); - if (savebuf != NULL && buf_valid(savebuf)) + if (savebuf != NULL && bufref_valid(&bufref)) wipe_buffer(savebuf, FALSE); #ifdef FEAT_DIFF @@ -8739,6 +8749,7 @@ ex_doautoall(exarg_T *eap) int retval; aco_save_T aco; buf_T *buf; + bufref_T bufref; char_u *arg = eap->arg; int call_do_modelines = check_nomodeline(&arg); int did_aucmd; @@ -8756,6 +8767,7 @@ ex_doautoall(exarg_T *eap) { /* find a window for this buffer and save some values */ aucmd_prepbuf(&aco, buf); + set_bufref(&bufref, buf); /* execute the autocommands for this buffer */ retval = do_doautocmd(arg, FALSE, &did_aucmd); @@ -8772,7 +8784,7 @@ ex_doautoall(exarg_T *eap) aucmd_restbuf(&aco); /* stop if there is some error or buffer was deleted */ - if (retval == FAIL || !buf_valid(buf)) + if (retval == FAIL || !bufref_valid(&bufref)) break; } } @@ -8898,7 +8910,7 @@ aucmd_prepbuf( } curbuf = buf; aco->new_curwin = curwin; - aco->new_curbuf = curbuf; + set_bufref(&aco->new_curbuf, curbuf); } /* @@ -8992,16 +9004,16 @@ win_found: * it was changed, we are still the same window and the buffer is * valid. */ if (curwin == aco->new_curwin - && curbuf != aco->new_curbuf - && buf_valid(aco->new_curbuf) - && aco->new_curbuf->b_ml.ml_mfp != NULL) + && curbuf != aco->new_curbuf.br_buf + && bufref_valid(&aco->new_curbuf) + && aco->new_curbuf.br_buf->b_ml.ml_mfp != NULL) { # if defined(FEAT_SYN_HL) || defined(FEAT_SPELL) if (curwin->w_s == &curbuf->b_s) - curwin->w_s = &aco->new_curbuf->b_s; + curwin->w_s = &aco->new_curbuf.br_buf->b_s; # endif --curbuf->b_nwindows; - curbuf = aco->new_curbuf; + curbuf = aco->new_curbuf.br_buf; curwin->w_buffer = curbuf; ++curbuf->b_nwindows; } @@ -9180,6 +9192,10 @@ has_funcundefined(void) return (first_autopat[(int)EVENT_FUNCUNDEFINED] != NULL); } +/* + * Execute autocommands for "event" and file name "fname". + * Return TRUE if some commands were executed. + */ static int apply_autocmds_group( event_T event, diff --git a/src/if_py_both.h b/src/if_py_both.h --- a/src/if_py_both.h +++ b/src/if_py_both.h @@ -3409,7 +3409,7 @@ set_option_value_for( { win_T *save_curwin = NULL; tabpage_T *save_curtab = NULL; - buf_T *save_curbuf = NULL; + bufref_T save_curbuf; int set_ret = 0; VimTryStart(); @@ -3431,7 +3431,7 @@ set_option_value_for( case SREQ_BUF: switch_buffer(&save_curbuf, (buf_T *)from); set_ret = set_option_value_err(key, numval, stringval, opt_flags); - restore_buffer(save_curbuf); + restore_buffer(&save_curbuf); break; case SREQ_GLOBAL: set_ret = set_option_value_err(key, numval, stringval, opt_flags); @@ -4273,17 +4273,17 @@ switch_to_win_for_buf( buf_T *buf, win_T **save_curwinp, tabpage_T **save_curtabp, - buf_T **save_curbufp) + bufref_T *save_curbuf) { win_T *wp; tabpage_T *tp; if (find_win_for_buf(buf, &wp, &tp) == FAIL) - switch_buffer(save_curbufp, buf); + switch_buffer(save_curbuf, buf); else if (switch_win(save_curwinp, save_curtabp, wp, tp, TRUE) == FAIL) { restore_win(*save_curwinp, *save_curtabp, TRUE); - switch_buffer(save_curbufp, buf); + switch_buffer(save_curbuf, buf); } } @@ -4291,9 +4291,9 @@ switch_to_win_for_buf( restore_win_for_buf( win_T *save_curwin, tabpage_T *save_curtab, - buf_T *save_curbuf) -{ - if (save_curbuf == NULL) + bufref_T *save_curbuf) +{ + if (save_curbuf->br_buf == NULL) restore_win(save_curwin, save_curtab, TRUE); else restore_buffer(save_curbuf); @@ -4311,7 +4311,7 @@ restore_win_for_buf( static int SetBufferLine(buf_T *buf, PyInt n, PyObject *line, PyInt *len_change) { - buf_T *save_curbuf = NULL; + bufref_T save_curbuf = {NULL, 0}; win_T *save_curwin = NULL; tabpage_T *save_curtab = NULL; @@ -4336,13 +4336,13 @@ SetBufferLine(buf_T *buf, PyInt n, PyObj { if (buf == curbuf) py_fix_cursor((linenr_T)n, (linenr_T)n + 1, (linenr_T)-1); - if (save_curbuf == NULL) + if (save_curbuf.br_buf == NULL) /* Only adjust marks if we managed to switch to a window that * holds the buffer, otherwise line numbers will be invalid. */ deleted_lines_mark((linenr_T)n, 1L); } - restore_win_for_buf(save_curwin, save_curtab, save_curbuf); + restore_win_for_buf(save_curwin, save_curtab, &save_curbuf); if (VimTryEnd()) return FAIL; @@ -4378,7 +4378,7 @@ SetBufferLine(buf_T *buf, PyInt n, PyObj else changed_bytes((linenr_T)n, 0); - restore_win_for_buf(save_curwin, save_curtab, save_curbuf); + restore_win_for_buf(save_curwin, save_curtab, &save_curbuf); /* Check that the cursor is not beyond the end of the line now. */ if (buf == curbuf) @@ -4415,7 +4415,7 @@ SetBufferLineList( PyObject *list, PyInt *len_change) { - buf_T *save_curbuf = NULL; + bufref_T save_curbuf = {NULL, 0}; win_T *save_curwin = NULL; tabpage_T *save_curtab = NULL; @@ -4446,17 +4446,18 @@ SetBufferLineList( break; } } - if (buf == curbuf && (save_curwin != NULL || save_curbuf == NULL)) + if (buf == curbuf && (save_curwin != NULL + || save_curbuf.br_buf == NULL)) /* Using an existing window for the buffer, adjust the cursor * position. */ py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)-n); - if (save_curbuf == NULL) + if (save_curbuf.br_buf == NULL) /* Only adjust marks if we managed to switch to a window that * holds the buffer, otherwise line numbers will be invalid. */ deleted_lines_mark((linenr_T)lo, (long)i); } - restore_win_for_buf(save_curwin, save_curtab, save_curbuf); + restore_win_for_buf(save_curwin, save_curtab, &save_curbuf); if (VimTryEnd()) return FAIL; @@ -4578,7 +4579,7 @@ SetBufferLineList( * changed range, and move any in the remainder of the buffer. * Only adjust marks if we managed to switch to a window that holds * the buffer, otherwise line numbers will be invalid. */ - if (save_curbuf == NULL) + if (save_curbuf.br_buf == NULL) mark_adjust((linenr_T)lo, (linenr_T)(hi - 1), (long)MAXLNUM, (long)extra); changed_lines((linenr_T)lo, 0, (linenr_T)hi, (long)extra); @@ -4587,7 +4588,7 @@ SetBufferLineList( py_fix_cursor((linenr_T)lo, (linenr_T)hi, (linenr_T)extra); /* END of region without "return". */ - restore_win_for_buf(save_curwin, save_curtab, save_curbuf); + restore_win_for_buf(save_curwin, save_curtab, &save_curbuf); if (VimTryEnd()) return FAIL; @@ -4615,7 +4616,7 @@ SetBufferLineList( static int InsertBufferLines(buf_T *buf, PyInt n, PyObject *lines, PyInt *len_change) { - buf_T *save_curbuf = NULL; + bufref_T save_curbuf = {NULL, 0}; win_T *save_curwin = NULL; tabpage_T *save_curtab = NULL; @@ -4637,13 +4638,13 @@ InsertBufferLines(buf_T *buf, PyInt n, P RAISE_UNDO_FAIL; else if (ml_append((linenr_T)n, (char_u *)str, 0, FALSE) == FAIL) RAISE_INSERT_LINE_FAIL; - else if (save_curbuf == NULL) + else if (save_curbuf.br_buf == NULL) /* Only adjust marks if we managed to switch to a window that * holds the buffer, otherwise line numbers will be invalid. */ appended_lines_mark((linenr_T)n, 1L); vim_free(str); - restore_win_for_buf(save_curwin, save_curtab, save_curbuf); + restore_win_for_buf(save_curwin, save_curtab, &save_curbuf); update_screen(VALID); if (VimTryEnd()) @@ -4704,7 +4705,7 @@ InsertBufferLines(buf_T *buf, PyInt n, P } vim_free(array[i]); } - if (i > 0 && save_curbuf == NULL) + if (i > 0 && save_curbuf.br_buf == NULL) /* Only adjust marks if we managed to switch to a window that * holds the buffer, otherwise line numbers will be invalid. */ appended_lines_mark((linenr_T)n, (long)i); @@ -4713,7 +4714,7 @@ InsertBufferLines(buf_T *buf, PyInt n, P /* Free the array of lines. All of its contents have now * been freed. */ PyMem_Free(array); - restore_win_for_buf(save_curwin, save_curtab, save_curbuf); + restore_win_for_buf(save_curwin, save_curtab, &save_curbuf); update_screen(VALID); @@ -5216,7 +5217,7 @@ BufferMark(BufferObject *self, PyObject pos_T *posp; char_u *pmark; char_u mark; - buf_T *savebuf; + bufref_T savebuf; PyObject *todecref; if (CheckBuffer(self)) @@ -5240,7 +5241,7 @@ BufferMark(BufferObject *self, PyObject VimTryStart(); switch_buffer(&savebuf, self->buf); posp = getmark(mark, FALSE); - restore_buffer(savebuf); + restore_buffer(&savebuf); if (VimTryEnd()) return NULL; diff --git a/src/main.c b/src/main.c --- a/src/main.c +++ b/src/main.c @@ -1460,9 +1460,13 @@ getout(int exitval) for (buf = firstbuf; buf != NULL; buf = buf->b_next) if (buf->b_ml.ml_mfp != NULL) { + bufref_T bufref; + + set_bufref(&bufref, buf); apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf); - if (!buf_valid(buf)) /* autocmd may delete the buffer */ + if (!bufref_valid(&bufref)) + /* autocmd deleted the buffer */ break; } apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf); diff --git a/src/misc2.c b/src/misc2.c --- a/src/misc2.c +++ b/src/misc2.c @@ -1173,9 +1173,12 @@ free_all_mem(void) #endif for (buf = firstbuf; buf != NULL; ) { + bufref_T bufref; + + set_bufref(&bufref, buf); nextbuf = buf->b_next; close_buffer(NULL, buf, DOBUF_WIPE, FALSE); - if (buf_valid(buf)) + if (bufref_valid(&bufref)) buf = nextbuf; /* didn't work, try next one */ else buf = firstbuf; diff --git a/src/netbeans.c b/src/netbeans.c --- a/src/netbeans.c +++ b/src/netbeans.c @@ -2177,10 +2177,15 @@ nb_do_cmd( #endif ) { +#ifdef FEAT_AUTOCMD + bufref_T bufref; + + set_bufref(&bufref, buf->bufp); +#endif buf_write_all(buf->bufp, FALSE); #ifdef FEAT_AUTOCMD /* an autocommand may have deleted the buffer */ - if (!buf_valid(buf->bufp)) + if (!bufref_valid(&bufref)) buf->bufp = NULL; #endif } diff --git a/src/proto/buffer.pro b/src/proto/buffer.pro --- a/src/proto/buffer.pro +++ b/src/proto/buffer.pro @@ -7,7 +7,7 @@ void close_buffer(win_T *win, buf_T *buf void buf_clear_file(buf_T *buf); void buf_freeall(buf_T *buf, int flags); void goto_buffer(exarg_T *eap, int start, int dir, int count); -void handle_swap_exists(buf_T *old_curbuf); +void handle_swap_exists(bufref_T *old_curbuf); char_u *do_bufdel(int command, char_u *arg, int addr_count, int start_bnr, int end_bnr, int forceit); int do_buffer(int action, int start, int dir, int count, int forceit); void set_curbuf(buf_T *buf, int action); diff --git a/src/proto/window.pro b/src/proto/window.pro --- a/src/proto/window.pro +++ b/src/proto/window.pro @@ -74,8 +74,8 @@ void make_snapshot(int idx); void restore_snapshot(int idx, int close_curwin); int switch_win(win_T **save_curwin, tabpage_T **save_curtab, win_T *win, tabpage_T *tp, int no_display); void restore_win(win_T *save_curwin, tabpage_T *save_curtab, int no_display); -void switch_buffer(buf_T **save_curbuf, buf_T *buf); -void restore_buffer(buf_T *save_curbuf); +void switch_buffer(bufref_T *save_curbuf, buf_T *buf); +void restore_buffer(bufref_T *save_curbuf); int win_hasvertsplit(void); int match_add(win_T *wp, char_u *grp, char_u *pat, int prio, int id, list_T *pos_list, char_u *conceal_char); int match_delete(win_T *wp, int id, int perr); diff --git a/src/quickfix.c b/src/quickfix.c --- a/src/quickfix.c +++ b/src/quickfix.c @@ -4242,7 +4242,8 @@ load_dummy_buffer( char_u *resulting_dir) /* out: new directory */ { buf_T *newbuf; - buf_T *newbuf_to_wipe = NULL; + bufref_T newbufref; + bufref_T newbuf_to_wipe; int failed = TRUE; aco_save_T aco; @@ -4250,6 +4251,7 @@ load_dummy_buffer( newbuf = buflist_new(NULL, NULL, (linenr_T)1, BLN_DUMMY); if (newbuf == NULL) return NULL; + set_bufref(&newbufref, newbuf); /* Init the options. */ buf_copy_options(newbuf, BCO_ENTER | BCO_NOHELP); @@ -4270,6 +4272,7 @@ load_dummy_buffer( * work. */ curbuf->b_flags &= ~BF_DUMMY; + newbuf_to_wipe.br_buf = NULL; if (readfile(fname, NULL, (linenr_T)0, (linenr_T)0, (linenr_T)MAXLNUM, NULL, READ_NEW | READ_DUMMY) == OK @@ -4283,15 +4286,15 @@ load_dummy_buffer( * using netrw and editing a remote file. Use the current * buffer instead, delete the dummy one after restoring the * window stuff. */ - newbuf_to_wipe = newbuf; + set_bufref(&newbuf_to_wipe, newbuf); newbuf = curbuf; } } /* restore curwin/curbuf and a few other things */ aucmd_restbuf(&aco); - if (newbuf_to_wipe != NULL && buf_valid(newbuf_to_wipe)) - wipe_buffer(newbuf_to_wipe, FALSE); + if (newbuf_to_wipe.br_buf != NULL && bufref_valid(&newbuf_to_wipe)) + wipe_buffer(newbuf_to_wipe.br_buf, FALSE); /* Add back the "dummy" flag, otherwise buflist_findname_stat() won't * skip it. */ @@ -4306,7 +4309,7 @@ load_dummy_buffer( mch_dirname(resulting_dir, MAXPATHL); restore_start_dir(dirname_start); - if (!buf_valid(newbuf)) + if (!bufref_valid(&newbufref)) return NULL; if (failed) { diff --git a/src/spell.c b/src/spell.c --- a/src/spell.c +++ b/src/spell.c @@ -4178,6 +4178,11 @@ did_set_spelllang(win_T *wp) static int recursive = FALSE; char_u *ret_msg = NULL; char_u *spl_copy; +#ifdef FEAT_AUTOCMD + bufref_T bufref; + + set_bufref(&bufref, wp->w_buffer); +#endif /* We don't want to do this recursively. May happen when a language is * not available and the SpellFileMissing autocommand opens a new buffer @@ -4278,7 +4283,7 @@ did_set_spelllang(win_T *wp) #ifdef FEAT_AUTOCMD /* SpellFileMissing autocommands may do anything, including * destroying the buffer we are using... */ - if (!buf_valid(wp->w_buffer)) + if (!bufref_valid(&bufref)) { ret_msg = (char_u *)"E797: SpellFileMissing autocommand deleted buffer"; goto theend; @@ -15561,7 +15566,7 @@ ex_spelldump(exarg_T *eap) set_option_value((char_u*)"spl", dummy, spl, OPT_LOCAL); vim_free(spl); - if (!bufempty() || !buf_valid(curbuf)) + if (!bufempty()) return; spell_dump_compl(NULL, 0, NULL, eap->forceit ? DUMPFLAG_COUNT : 0); diff --git a/src/structs.h b/src/structs.h --- a/src/structs.h +++ b/src/structs.h @@ -1431,7 +1431,7 @@ typedef struct { char_u *ch_callback; /* call when a msg is not handled */ partial_T *ch_partial; - buf_T *ch_buffer; /* buffer to read from or write to */ + bufref_T ch_bufref; /* buffer to read from or write to */ int ch_nomodifiable; /* TRUE when buffer can be 'nomodifiable' */ int ch_nomod_error; /* TRUE when e_modifiable was given */ int ch_buf_append; /* write appended lines instead top-bot */ @@ -2925,7 +2925,7 @@ typedef struct int use_aucmd_win; /* using aucmd_win */ win_T *save_curwin; /* saved curwin */ win_T *new_curwin; /* new curwin */ - buf_T *new_curbuf; /* new curbuf */ + bufref_T new_curbuf; /* new curbuf */ char_u *globaldir; /* saved value of globaldir */ #endif } aco_save_T; diff --git a/src/term.c b/src/term.c --- a/src/term.c +++ b/src/term.c @@ -1908,21 +1908,21 @@ set_termname(char_u *term) #ifdef FEAT_AUTOCMD { - buf_T *old_curbuf; + bufref_T old_curbuf; /* * Execute the TermChanged autocommands for each buffer that is * loaded. */ - old_curbuf = curbuf; + set_bufref(&old_curbuf, curbuf); for (curbuf = firstbuf; curbuf != NULL; curbuf = curbuf->b_next) { if (curbuf->b_ml.ml_mfp != NULL) apply_autocmds(EVENT_TERMCHANGED, NULL, NULL, FALSE, curbuf); } - if (buf_valid(old_curbuf)) - curbuf = old_curbuf; + if (bufref_valid(&old_curbuf)) + curbuf = old_curbuf.br_buf; } #endif } diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -759,6 +759,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 2024, +/**/ 2023, /**/ 2022, diff --git a/src/window.c b/src/window.c --- a/src/window.c +++ b/src/window.c @@ -2340,6 +2340,9 @@ win_close(win_T *win, int free_buf) */ if (win->w_buffer != NULL) { + bufref_T bufref; + + set_bufref(&bufref, curbuf); #ifdef FEAT_AUTOCMD win->w_closing = TRUE; #endif @@ -2350,7 +2353,7 @@ win_close(win_T *win, int free_buf) #endif /* Make sure curbuf is valid. It can become invalid if 'bufhidden' is * "wipe". */ - if (!buf_valid(curbuf)) + if (!bufref_valid(&bufref)) curbuf = firstbuf; } @@ -6632,12 +6635,12 @@ restore_win( * No autocommands will be executed. Use aucmd_prepbuf() if there are any. */ void -switch_buffer(buf_T **save_curbuf, buf_T *buf) +switch_buffer(bufref_T *save_curbuf, buf_T *buf) { # ifdef FEAT_AUTOCMD block_autocmds(); # endif - *save_curbuf = curbuf; + set_bufref(save_curbuf, curbuf); --curbuf->b_nwindows; curbuf = buf; curwin->w_buffer = buf; @@ -6648,17 +6651,17 @@ switch_buffer(buf_T **save_curbuf, buf_T * Restore the current buffer after using switch_buffer(). */ void -restore_buffer(buf_T *save_curbuf) +restore_buffer(bufref_T *save_curbuf) { # ifdef FEAT_AUTOCMD unblock_autocmds(); # endif /* Check for valid buffer, just in case. */ - if (buf_valid(save_curbuf)) + if (bufref_valid(save_curbuf)) { --curbuf->b_nwindows; - curwin->w_buffer = save_curbuf; - curbuf = save_curbuf; + curwin->w_buffer = save_curbuf->br_buf; + curbuf = save_curbuf->br_buf; ++curbuf->b_nwindows; } }