diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak index 005df196ae..e0638abb9b 100644 --- a/src/Make_cyg_ming.mak +++ b/src/Make_cyg_ming.mak @@ -893,7 +893,7 @@ if_perl.c: if_perl.xs typemap $(PERLTYPEMAP) if_perl.xs > $@ $(OUTDIR)/iscygpty.o: iscygpty.c $(CUI_INCL) - $(CC) -c $(CFLAGS) iscygpty.c -o $(OUTDIR)/iscygpty.o -D_WIN32_WINNT=0x0600 -DUSE_DYNFILEID -DENABLE_STUB_IMPL + $(CC) -c $(CFLAGS) iscygpty.c -o $(OUTDIR)/iscygpty.o -U_WIN32_WINNT -D_WIN32_WINNT=0x0600 -DUSE_DYNFILEID -DENABLE_STUB_IMPL $(OUTDIR)/main.o: main.c $(INCL) $(CUI_INCL) $(CC) -c $(CFLAGS) main.c -o $(OUTDIR)/main.o diff --git a/src/buffer.c b/src/buffer.c index 80bdccad21..10d5a9e1e4 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -67,6 +67,9 @@ static char *msg_qflist = N_("[Quickfix List]"); static char *e_auabort = N_("E855: Autocommands caused command to abort"); #endif +/* Number of times free_buffer() was called. */ +static int buf_free_count = 0; + /* * Open current buffer, that is: open the memfile and read the file into * memory. @@ -80,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; @@ -126,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 @@ -281,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); @@ -308,15 +311,39 @@ open_buffer( return retval; } +/* + * Store "buf" in "bufref" and set the free count. + */ + void +set_bufref(bufref_T *bufref, buf_T *buf) +{ + bufref->br_buf = buf; + bufref->br_buf_free_count = buf_free_count; +} + +/* + * Return TRUE if "bufref->br_buf" points to a valid buffer. + * Only goes through the buffer list if buf_free_count changed. + */ + int +bufref_valid(bufref_T *bufref) +{ + return bufref->br_buf_free_count == buf_free_count + ? TRUE : buf_valid(bufref->br_buf); +} + /* * Return TRUE if "buf" points to a valid buffer (in the buffer list). + * This can be slow if there are many buffers, prefer using bufref_valid(). */ int buf_valid(buf_T *buf) { buf_T *bp; - for (bp = firstbuf; bp != NULL; bp = bp->b_next) + /* Assume that we more often have a recent buffer, start with the last + * one. */ + for (bp = lastbuf; bp != NULL; bp = bp->b_prev) if (bp == buf) return TRUE; return FALSE; @@ -349,6 +376,7 @@ close_buffer( #ifdef FEAT_AUTOCMD int is_curbuf; int nwindows; + bufref_T bufref; #endif int unload_buf = (action != 0); int del_buf = (action == DOBUF_DEL || action == DOBUF_WIPE); @@ -393,13 +421,15 @@ close_buffer( } #ifdef FEAT_AUTOCMD + set_bufref(&bufref, buf); + /* When the buffer is no longer in a window, trigger BufWinLeave */ if (buf->b_nwindows == 1) { buf->b_closing = TRUE; - apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname, - FALSE, buf); - if (!buf_valid(buf)) + if (apply_autocmds(EVENT_BUFWINLEAVE, buf->b_fname, buf->b_fname, + FALSE, buf) + && !bufref_valid(&bufref)) { /* Autocommands deleted the buffer. */ aucmd_abort: @@ -416,9 +446,9 @@ aucmd_abort: if (!unload_buf) { buf->b_closing = TRUE; - apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname, - FALSE, buf); - if (!buf_valid(buf)) + if (apply_autocmds(EVENT_BUFHIDDEN, buf->b_fname, buf->b_fname, + FALSE, buf) + && !bufref_valid(&bufref)) /* Autocommands deleted the buffer. */ goto aucmd_abort; buf->b_closing = FALSE; @@ -462,7 +492,7 @@ aucmd_abort: #ifdef FEAT_AUTOCMD /* Autocommands may have deleted the buffer. */ - if (!buf_valid(buf)) + if (!bufref_valid(&bufref)) return; # ifdef FEAT_EVAL if (aborting()) /* autocmds may abort script processing */ @@ -577,25 +607,32 @@ buf_freeall(buf_T *buf, int flags) { #ifdef FEAT_AUTOCMD int is_curbuf = (buf == curbuf); + bufref_T bufref; buf->b_closing = TRUE; + set_bufref(&bufref, buf); if (buf->b_ml.ml_mfp != NULL) { - apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, FALSE, buf); - if (!buf_valid(buf)) /* autocommands may delete the buffer */ + if (apply_autocmds(EVENT_BUFUNLOAD, buf->b_fname, buf->b_fname, + FALSE, buf) + && !bufref_valid(&bufref)) + /* autocommands deleted the buffer */ return; } if ((flags & BFA_DEL) && buf->b_p_bl) { - apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname, FALSE, buf); - if (!buf_valid(buf)) /* autocommands may delete the buffer */ + if (apply_autocmds(EVENT_BUFDELETE, buf->b_fname, buf->b_fname, + FALSE, buf) + && !bufref_valid(&bufref)) + /* autocommands deleted the buffer */ return; } if (flags & BFA_WIPE) { - apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname, - FALSE, buf); - if (!buf_valid(buf)) /* autocommands may delete the buffer */ + if (apply_autocmds(EVENT_BUFWIPEOUT, buf->b_fname, buf->b_fname, + FALSE, buf) + && !bufref_valid(&bufref)) + /* autocommands deleted the buffer */ return; } buf->b_closing = FALSE; @@ -662,6 +699,7 @@ buf_freeall(buf_T *buf, int flags) static void free_buffer(buf_T *buf) { + ++buf_free_count; free_buffer_stuff(buf, TRUE); #ifdef FEAT_EVAL unref_var_dict(buf->b_vars); @@ -775,7 +813,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 @@ -804,7 +844,7 @@ goto_buffer( # endif } else - handle_swap_exists(old_curbuf); + handle_swap_exists(&old_curbuf); # endif } #endif @@ -815,7 +855,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; @@ -823,6 +863,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) { @@ -838,11 +879,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); @@ -1027,6 +1071,7 @@ empty_curbuf( { int retval; buf_T *buf = curbuf; + bufref_T bufref; if (action == DOBUF_UNLOAD) { @@ -1034,13 +1079,12 @@ empty_curbuf( return FAIL; } - if (close_others) - { - /* Close any other windows on this buffer, then make it empty. */ + set_bufref(&bufref, buf); #ifdef FEAT_WINDOWS + if (close_others) + /* Close any other windows on this buffer, then make it empty. */ close_windows(buf, TRUE); #endif - } setpcmark(); retval = do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, @@ -1051,7 +1095,7 @@ empty_curbuf( * 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) + if (buf != curbuf && bufref_valid(&bufref) && buf->b_nwindows == 0) close_buffer(NULL, buf, action, FALSE); if (!close_others) need_fileinfo = FALSE; @@ -1177,6 +1221,11 @@ do_buffer( if (unload) { int forward; +# if defined(FEAT_AUTOCMD) || defined(FEAT_WINDOWS) + bufref_T bufref; + + set_bufref(&bufref, buf); +# endif /* When unloading or deleting a buffer that's already unloaded and * unlisted: fail silently. */ @@ -1190,7 +1239,7 @@ do_buffer( { dialog_changed(buf, FALSE); # ifdef FEAT_AUTOCMD - if (!buf_valid(buf)) + if (!bufref_valid(&bufref)) /* Autocommand deleted buffer, oops! It's not changed * now. */ return FAIL; @@ -1243,9 +1292,10 @@ do_buffer( { #ifdef FEAT_WINDOWS close_windows(buf, FALSE); + if (buf != curbuf && bufref_valid(&bufref)) #endif - if (buf != curbuf && buf_valid(buf) && buf->b_nwindows <= 0) - close_buffer(NULL, buf, action, FALSE); + if (buf->b_nwindows <= 0) + close_buffer(NULL, buf, action, FALSE); return OK; } @@ -1253,7 +1303,7 @@ do_buffer( * 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. + * First use au_new_curbuf.br_buf, if it is valid. * Then prefer the buffer we most recently visited. * Else try to find one that is loaded, after the current buffer, * then before the current buffer. @@ -1262,8 +1312,8 @@ do_buffer( buf = NULL; /* selected buffer */ bp = NULL; /* used when no loaded buffer found */ #ifdef FEAT_AUTOCMD - if (au_new_curbuf != NULL && buf_valid(au_new_curbuf)) - buf = au_new_curbuf; + if (au_new_curbuf.br_buf != NULL && bufref_valid(&au_new_curbuf)) + buf = au_new_curbuf.br_buf; # ifdef FEAT_JUMPLIST else # endif @@ -1390,9 +1440,14 @@ do_buffer( #if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) if ((p_confirm || cmdmod.confirm) && p_write) { +# ifdef FEAT_AUTOCMD + bufref_T bufref; + + set_bufref(&bufref, buf); +# endif dialog_changed(curbuf, FALSE); # ifdef FEAT_AUTOCMD - if (!buf_valid(buf)) + if (!bufref_valid(&bufref)) /* Autocommand deleted buffer, oops! */ return FAIL; # endif @@ -1443,6 +1498,7 @@ set_curbuf(buf_T *buf, int action) #ifdef FEAT_SYN_HL long old_tw = curbuf->b_p_tw; #endif + bufref_T bufref; setpcmark(); if (!cmdmod.keepalt) @@ -1454,13 +1510,14 @@ set_curbuf(buf_T *buf, int action) /* close_windows() or apply_autocmds() may change curbuf */ prevbuf = curbuf; + set_bufref(&bufref, prevbuf); #ifdef FEAT_AUTOCMD - apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); + if (!apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf) # ifdef FEAT_EVAL - if (buf_valid(prevbuf) && !aborting()) + || (bufref_valid(&bufref) && !aborting())) # else - if (buf_valid(prevbuf)) + || bufref_valid(&bufref)) # endif #endif { @@ -1473,9 +1530,9 @@ set_curbuf(buf_T *buf, int action) close_windows(prevbuf, FALSE); #endif #if defined(FEAT_AUTOCMD) && defined(FEAT_EVAL) - if (buf_valid(prevbuf) && !aborting()) + if (bufref_valid(&bufref) && !aborting()) #else - if (buf_valid(prevbuf)) + if (bufref_valid(&bufref)) #endif { #ifdef FEAT_WINDOWS @@ -1496,7 +1553,7 @@ set_curbuf(buf_T *buf, int action) } #ifdef FEAT_AUTOCMD /* An autocommand may have deleted "buf", already entered it (e.g., when - * it did ":bunload") or aborted the script processing! + * it did ":bunload") or aborted the script processing. * If curwin->w_buffer is null, enter_buffer() will make it valid again */ if ((buf_valid(buf) && buf != curbuf # ifdef FEAT_EVAL @@ -1658,6 +1715,8 @@ do_autochdir(void) * If (flags & BLN_LISTED) is TRUE, add new buffer to buffer list. * If (flags & BLN_DUMMY) is TRUE, don't count it as a real buffer. * If (flags & BLN_NEW) is TRUE, don't use an existing buffer. + * If (flags & BLN_NOOPT) is TRUE, don't copy options from the current buffer + * if the buffer already exists. * This is the ONLY way to create a new buffer. */ static int top_file_num = 1; /* highest file number */ @@ -1696,17 +1755,24 @@ buflist_new( vim_free(ffname); if (lnum != 0) buflist_setfpos(buf, curwin, lnum, (colnr_T)0, FALSE); - /* copy the options now, if 'cpo' doesn't have 's' and not done - * already */ - buf_copy_options(buf, 0); + + if ((flags & BLN_NOOPT) == 0) + /* copy the options now, if 'cpo' doesn't have 's' and not done + * already */ + buf_copy_options(buf, 0); + if ((flags & BLN_LISTED) && !buf->b_p_bl) { +#ifdef FEAT_AUTOCMD + bufref_T bufref; +#endif buf->b_p_bl = TRUE; #ifdef FEAT_AUTOCMD + set_bufref(&bufref, buf); if (!(flags & BLN_DUMMY)) { - apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf); - if (!buf_valid(buf)) + if (apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf) + && !bufref_valid(&bufref)) return NULL; } #endif @@ -1882,16 +1948,19 @@ buflist_new( #ifdef FEAT_AUTOCMD if (!(flags & BLN_DUMMY)) { + bufref_T bufref; + /* Tricky: these autocommands may change the buffer list. They could * also split the window with re-using the one empty buffer. This may * result in unexpectedly losing the empty buffer. */ - apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf); - if (!buf_valid(buf)) + set_bufref(&bufref, buf); + if (apply_autocmds(EVENT_BUFNEW, NULL, NULL, FALSE, buf) + && !bufref_valid(&bufref)) return NULL; if (flags & BLN_LISTED) { - apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf); - if (!buf_valid(buf)) + if (apply_autocmds(EVENT_BUFADD, NULL, NULL, FALSE, buf) + && !bufref_valid(&bufref)) return NULL; } # ifdef FEAT_EVAL @@ -2211,7 +2280,8 @@ buflist_findname_stat( #endif buf_T *buf; - for (buf = firstbuf; buf != NULL; buf = buf->b_next) + /* Start at the last buffer, expect to find a match sooner. */ + for (buf = lastbuf; buf != NULL; buf = buf->b_prev) if ((buf->b_flags & BF_DUMMY) == 0 && !otherfile_buf(buf, ffname #ifdef UNIX , stp @@ -2296,7 +2366,7 @@ buflist_findpat( return -1; } - for (buf = firstbuf; buf != NULL; buf = buf->b_next) + for (buf = lastbuf; buf != NULL; buf = buf->b_prev) if (buf->b_p_bl == find_listed #ifdef FEAT_DIFF && (!diffmode || diff_mode_buf(buf)) @@ -2522,7 +2592,8 @@ buflist_findnr(int nr) if (nr == 0) nr = curwin->w_alt_fnum; - for (buf = firstbuf; buf != NULL; buf = buf->b_next) + /* Assume newer buffers are used more often, start from the end. */ + for (buf = lastbuf; buf != NULL; buf = buf->b_prev) if (buf->b_fnum == nr) return buf; return NULL; @@ -4709,10 +4780,15 @@ do_arg_all( if (!P_HID(buf) && buf->b_nwindows <= 1 && bufIsChanged(buf)) { +#ifdef FEAT_AUTOCMD + bufref_T bufref; + + set_bufref(&bufref, buf); +#endif (void)autowrite(buf, FALSE); #ifdef FEAT_AUTOCMD /* check if autocommands removed the window */ - if (!win_valid(wp) || !buf_valid(buf)) + if (!win_valid(wp) || !bufref_valid(&bufref)) { wpnext = firstwin; /* start all over... */ continue; @@ -4994,6 +5070,11 @@ ex_buffer_all(exarg_T *eap) if (wp == NULL && split_ret == OK) { +#ifdef FEAT_AUTOCMD + bufref_T bufref; + + set_bufref(&bufref, buf); +#endif /* Split the window and put the buffer in it */ p_ea_save = p_ea; p_ea = TRUE; /* use space from all windows */ @@ -5009,8 +5090,9 @@ ex_buffer_all(exarg_T *eap) #endif set_curbuf(buf, DOBUF_GOTO); #ifdef FEAT_AUTOCMD - if (!buf_valid(buf)) /* autocommands deleted the buffer!!! */ + if (!bufref_valid(&bufref)) { + /* autocommands deleted the buffer!!! */ #if defined(HAS_SWAP_EXISTS_ACTION) swap_exists_action = SEA_NONE; # endif diff --git a/src/channel.c b/src/channel.c index 795253722b..47c079aee2 100644 --- a/src/channel.c +++ b/src/channel.c @@ -367,7 +367,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 @@ -384,9 +384,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); } /* @@ -1067,19 +1069,19 @@ channel_set_job(channel_T *channel, job_T *job, jobopt_T *options) { 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; @@ -1089,7 +1091,7 @@ channel_set_job(channel_T *channel, job_T *job, jobopt_T *options) 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; } } @@ -1250,7 +1252,7 @@ channel_set_options(channel_T *channel, jobopt_T *opt) { 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); } } } @@ -1265,7 +1267,7 @@ channel_set_options(channel_T *channel, jobopt_T *opt) 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]); @@ -1287,7 +1289,7 @@ channel_set_options(channel_T *channel, jobopt_T *opt) { 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); } } } @@ -1428,15 +1430,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; } @@ -1458,7 +1460,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 @@ -1480,11 +1482,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; } } } @@ -1501,10 +1503,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); } @@ -1528,7 +1530,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 */ @@ -2333,7 +2335,7 @@ append_to_buffer(buf_T *buffer, char_u *msg, channel_T *channel, int part) { 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; } } @@ -2395,11 +2397,11 @@ may_invoke_callback(channel_T *channel, int part) 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; } @@ -2855,7 +2857,7 @@ channel_fill_wfds(int maxfd_arg, fd_set *wfds) { 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) @@ -2878,7 +2880,7 @@ channel_fill_poll_write(int nfd_in, struct pollfd *fds) { 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; @@ -3668,8 +3670,8 @@ channel_poll_check(int ret_in, void *fds_in) { 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); @@ -3746,8 +3748,8 @@ channel_select_check(int ret_in, void *rfds_in, void *wfds_in) { 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 index 5e17943ec5..287f434bee 100644 --- 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 index 173091e029..6fe8398c3e 100644 --- a/src/eval.c +++ b/src/eval.c @@ -10503,8 +10503,9 @@ f_ch_getbufnr(typval_T *argvars, typval_T *rettv) 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; } } @@ -13115,7 +13116,7 @@ f_getcompletion(typval_T *argvars, typval_T *rettv) ExpandInit(&xpc); xpc.xp_pattern = get_tv_string(&argvars[0]); - xpc.xp_pattern_len = STRLEN(xpc.xp_pattern); + xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern); xpc.xp_context = cmdcomplete_str_to_type(get_tv_string(&argvars[1])); if (xpc.xp_context == EXPAND_NOTHING) { @@ -13129,7 +13130,7 @@ f_getcompletion(typval_T *argvars, typval_T *rettv) if (xpc.xp_context == EXPAND_MENUS) { set_context_in_menu_cmd(&xpc, (char_u *)"menu", xpc.xp_pattern, FALSE); - xpc.xp_pattern_len = STRLEN(xpc.xp_pattern); + xpc.xp_pattern_len = (int)STRLEN(xpc.xp_pattern); } pat = addstar(xpc.xp_pattern, xpc.xp_pattern_len, xpc.xp_context); diff --git a/src/ex_cmds.c b/src/ex_cmds.c index d93a7ec7fc..7ec17b132c 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -3447,11 +3447,16 @@ do_wqall(exarg_T *eap) } else { +#ifdef FEAT_AUTOCMD + bufref_T bufref; + + set_bufref(&bufref, buf); +#endif if (buf_write_all(buf, eap->forceit) == FAIL) ++error; #ifdef FEAT_AUTOCMD /* an autocommand may have deleted the buffer */ - if (!buf_valid(buf)) + if (!bufref_valid(&bufref)) buf = firstbuf; #endif } @@ -3659,8 +3664,9 @@ do_ecmd( int did_set_swapcommand = FALSE; #endif 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 @@ -3685,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) { @@ -3851,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) @@ -3863,12 +3872,13 @@ do_ecmd( else /* existing memfile */ { oldbuf = TRUE; + set_bufref(&bufref, buf); (void)buf_check_timestamp(buf, FALSE); /* Check if autocommands made buffer invalid or changed the current * buffer. */ - if (!buf_valid(buf) + if (!bufref_valid(&bufref) #ifdef FEAT_AUTOCMD - || curbuf != old_curbuf + || curbuf != old_curbuf.br_buf #endif ) goto theend; @@ -3908,10 +3918,11 @@ do_ecmd( */ if (buf->b_fname != NULL) new_name = vim_strsave(buf->b_fname); - au_new_curbuf = buf; + set_bufref(&au_new_curbuf, buf); apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf); - if (!buf_valid(buf)) /* new buffer has been deleted */ + if (!bufref_valid(&au_new_curbuf)) { + /* new buffer has been deleted */ delbuf_msg(new_name); /* frees new_name */ goto theend; } @@ -3926,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); @@ -3951,8 +3962,9 @@ do_ecmd( } # endif /* Be careful again, like above. */ - if (!buf_valid(buf)) /* new buffer has been deleted */ + if (!bufref_valid(&au_new_curbuf)) { + /* new buffer has been deleted */ delbuf_msg(new_name); /* frees new_name */ goto theend; } @@ -3995,7 +4007,7 @@ do_ecmd( #ifdef FEAT_AUTOCMD } vim_free(new_name); - au_new_curbuf = NULL; + au_new_curbuf.br_buf = NULL; #endif } @@ -4071,6 +4083,7 @@ do_ecmd( new_name = vim_strsave(buf->b_fname); else new_name = NULL; + set_bufref(&bufref, buf); #endif if (p_ur < 0 || curbuf->b_ml.ml_line_count <= p_ur) { @@ -4091,7 +4104,7 @@ do_ecmd( #ifdef FEAT_AUTOCMD /* If autocommands deleted the buffer we were going to re-edit, give * up and jump to the end. */ - if (!buf_valid(buf)) + if (!bufref_valid(&bufref)) { delbuf_msg(new_name); /* frees new_name */ goto theend; @@ -4186,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 @@ -4375,7 +4388,7 @@ delbuf_msg(char_u *name) EMSG2(_("E143: Autocommands unexpectedly deleted new buffer %s"), name == NULL ? (char_u *)"" : name); vim_free(name); - au_new_curbuf = NULL; + au_new_curbuf.br_buf = NULL; } #endif diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c index 3d8a582e4b..ec71be6717 100644 --- 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 @@ -1940,6 +1952,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); @@ -1950,7 +1967,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 } @@ -2056,11 +2073,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 */ } } @@ -2103,10 +2123,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 index 16bf8998e3..49c5e8b891 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -7339,8 +7339,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 index 96371eec31..08c65d81c2 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -1674,7 +1674,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; @@ -1682,7 +1682,7 @@ getcmdline( ccline.overstrike = FALSE; } else /* Hebrew is default */ -#endif +# endif cmd_hkmap = !cmd_hkmap; goto cmdline_not_changed; #endif @@ -6669,9 +6669,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; @@ -6700,6 +6700,7 @@ ex_window(void) beep_flush(); return K_IGNORE; } + set_bufref(&old_curbuf, curbuf); /* Save current window sizes. */ win_size_save(&winsizes); @@ -6846,7 +6847,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")); @@ -6917,14 +6918,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 index 681d6f9053..880964f4b6 100644 --- 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 @@ -6686,10 +6688,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. */ @@ -6780,6 +6785,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 @@ -6792,8 +6798,10 @@ buf_check_timestamp( static int busy = FALSE; int n; char_u *s; + bufref_T bufref; + + set_bufref(&bufref, buf); #endif - char *reason; /* 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 @@ -6882,7 +6890,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); @@ -7064,7 +7072,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 @@ -7091,6 +7099,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; @@ -7128,6 +7137,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. */ @@ -7160,7 +7170,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. */ @@ -7188,7 +7198,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 @@ -8777,6 +8787,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; @@ -8794,6 +8805,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); @@ -8810,7 +8822,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; } } @@ -8936,7 +8948,7 @@ aucmd_prepbuf( } curbuf = buf; aco->new_curwin = curwin; - aco->new_curbuf = curbuf; + set_bufref(&aco->new_curbuf, curbuf); } /* @@ -9030,16 +9042,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; } @@ -9218,6 +9230,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/globals.h b/src/globals.h index b4087824a9..3de533f500 100644 --- a/src/globals.h +++ b/src/globals.h @@ -386,7 +386,7 @@ EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when /* When deleting the current buffer, another one must be loaded. If we know * which one is preferred, au_new_curbuf is set to it */ -EXTERN buf_T *au_new_curbuf INIT(= NULL); +EXTERN bufref_T au_new_curbuf INIT(= {NULL}); /* When deleting a buffer/window and autocmd_busy is TRUE, do not free the * buffer/window. but link it in the list starting with diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c index 39b918ab83..9437ed3b17 100644 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -867,7 +867,10 @@ gui_mch_stop_blink(void) blink_timer = 0; } if (blink_state == BLINK_OFF) + { gui_update_cursor(TRUE, FALSE); + gui_mch_flush(); + } blink_state = BLINK_NONE; } @@ -902,6 +905,7 @@ blink_cb(gpointer data UNUSED) (GtkFunction) blink_cb, NULL); #endif } + gui_mch_flush(); return FALSE; /* don't happen again */ } @@ -934,6 +938,7 @@ gui_mch_start_blink(void) #endif blink_state = BLINK_ON; gui_update_cursor(TRUE, FALSE); + gui_mch_flush(); } } diff --git a/src/if_py_both.h b/src/if_py_both.h index 50fd687d96..062f8226d7 100644 --- 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) + bufref_T *save_curbuf) { - if (save_curbuf == NULL) + 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, PyObject *line, PyInt *len_change) { 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, PyObject *line, PyInt *len_change) 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, PyObject *lines, PyInt *len_change) 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, PyObject *lines, PyInt *len_change) } 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, PyObject *lines, PyInt *len_change) /* 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 *pmarkObject) 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 *pmarkObject) 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 index 624affc33a..6392c8d6c9 100644 --- a/src/main.c +++ b/src/main.c @@ -1529,9 +1529,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/mbyte.c b/src/mbyte.c index 22eadd0891..1a12e35c82 100644 --- a/src/mbyte.c +++ b/src/mbyte.c @@ -3067,6 +3067,9 @@ utf_convert( int utf_fold(int a) { + if (a < 0x80) + /* be fast for ASCII */ + return a >= 0x41 && a <= 0x5a ? a + 32 : a; return utf_convert(a, foldCase, (int)sizeof(foldCase)); } diff --git a/src/misc2.c b/src/misc2.c index 951328556a..bddce5e6c6 100644 --- 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 index 925560769f..f9434d6c0e 100644 --- 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/option.c b/src/option.c index 27881800a0..88fb293bf9 100644 --- a/src/option.c +++ b/src/option.c @@ -10803,12 +10803,6 @@ buf_copy_options(buf_T *buf, int flags) int dont_do_help; int did_isk = FALSE; - /* - * Don't do anything if the buffer is invalid. - */ - if (buf == NULL || !buf_valid(buf)) - return; - /* * Skip this when the option defaults have not been set yet. Happens when * main() allocates the first buffer. diff --git a/src/proto/buffer.pro b/src/proto/buffer.pro index 71217287a6..183f79a408 100644 --- a/src/proto/buffer.pro +++ b/src/proto/buffer.pro @@ -1,11 +1,13 @@ /* buffer.c */ int open_buffer(int read_stdin, exarg_T *eap, int flags); +void set_bufref(bufref_T *bufref, buf_T *buf); +int bufref_valid(bufref_T *bufref); int buf_valid(buf_T *buf); void close_buffer(win_T *win, buf_T *buf, int action, int abort_if_last); 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 index 05b6b9daeb..e091e34ad8 100644 --- 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 index 92a0204174..c60e98fdf9 100644 --- a/src/quickfix.c +++ b/src/quickfix.c @@ -1482,6 +1482,13 @@ copy_loclist(win_T *from, win_T *to) to->w_llist->qf_curlist = qi->qf_curlist; /* current list */ } +/* + * Looking up a buffer can be slow if there are many. Remember the last one + * to make this a lot faster if there are multiple matches in the same file. + */ +static char_u *qf_last_bufname = NULL; +static bufref_T qf_last_bufref = {NULL, 0}; + /* * Get buffer number for file "dir.name". * Also sets the b_has_qf_entry flag. @@ -1489,8 +1496,9 @@ copy_loclist(win_T *from, win_T *to) static int qf_get_fnum(qf_info_T *qi, char_u *directory, char_u *fname) { - char_u *ptr; + char_u *ptr = NULL; buf_T *buf; + char_u *bufname; if (fname == NULL || *fname == NUL) /* no file name */ return 0; @@ -1522,13 +1530,30 @@ qf_get_fnum(qf_info_T *qi, char_u *directory, char_u *fname) ptr = vim_strsave(fname); } /* Use concatenated directory name and file name */ - buf = buflist_new(ptr, NULL, (linenr_T)0, 0); + bufname = ptr; + } + else + bufname = fname; + + if (qf_last_bufname != NULL && STRCMP(bufname, qf_last_bufname) == 0 + && bufref_valid(&qf_last_bufref)) + { + buf = qf_last_bufref.br_buf; vim_free(ptr); } else - buf = buflist_new(fname, NULL, (linenr_T)0, 0); + { + vim_free(qf_last_bufname); + buf = buflist_new(bufname, NULL, (linenr_T)0, BLN_NOOPT); + if (bufname == ptr) + qf_last_bufname = bufname; + else + qf_last_bufname = vim_strsave(bufname); + set_bufref(&qf_last_bufref, buf); + } if (buf == NULL) return 0; + buf->b_has_qf_entry = TRUE; return buf->b_fnum; } @@ -4217,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; @@ -4225,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); @@ -4245,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 @@ -4258,15 +4286,19 @@ 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. */ + newbuf->b_flags |= BF_DUMMY; } /* @@ -4277,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/screen.c b/src/screen.c index 2c78eb4509..55ffce6d88 100644 --- a/src/screen.c +++ b/src/screen.c @@ -757,7 +757,7 @@ update_screen(int type) if (gui.in_use) { out_flush(); /* required before updating the cursor */ - if (did_one) + if (did_one && !gui_mch_is_blink_off()) { /* Put the GUI position where the cursor was, gui_update_cursor() * uses that. */ diff --git a/src/spell.c b/src/spell.c index 610c7b8202..af96891076 100644 --- 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 index bb542ae98c..8a25c56941 100644 --- a/src/structs.h +++ b/src/structs.h @@ -69,6 +69,14 @@ typedef struct frame_S frame_T; typedef int scid_T; /* script ID */ typedef struct file_buffer buf_T; /* forward declaration */ +/* Reference to a buffer that stores the value of buf_free_count. + * bufref_valid() only needs to check "buf" when the count differs. + */ +typedef struct { + buf_T *br_buf; + int br_buf_free_count; +} bufref_T; + /* * This is here because regexp.h needs pos_T and below regprog_T is used. */ @@ -1426,7 +1434,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 */ @@ -2936,7 +2944,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 index 91f0e18764..9778c767bb 100644 --- a/src/term.c +++ b/src/term.c @@ -1914,21 +1914,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 index 98fed3c932..9d67552967 100644 --- a/src/version.c +++ b/src/version.c @@ -773,6 +773,26 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2025, +/**/ + 2024, +/**/ + 2023, +/**/ + 2022, +/**/ + 2021, +/**/ + 2020, +/**/ + 2019, +/**/ + 2018, +/**/ + 2017, +/**/ + 2016, /**/ 2015, /**/ diff --git a/src/vim.h b/src/vim.h index f3cf07d545..09362a7a29 100644 --- a/src/vim.h +++ b/src/vim.h @@ -944,6 +944,7 @@ extern char *(*dyn_libintl_textdomain)(const char *domainname); #define BLN_LISTED 2 /* put new buffer in buffer list */ #define BLN_DUMMY 4 /* allocating dummy buffer */ #define BLN_NEW 8 /* create a new buffer */ +#define BLN_NOOPT 16 /* don't copy options to existing buffer */ /* Values for in_cinkeys() */ #define KEY_OPEN_FORW 0x101 diff --git a/src/window.c b/src/window.c index 8683822389..6f00f515cf 100644 --- a/src/window.c +++ b/src/window.c @@ -2345,6 +2345,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 @@ -2355,7 +2358,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; } @@ -6642,12 +6645,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; @@ -6658,17 +6661,17 @@ switch_buffer(buf_T **save_curbuf, buf_T *buf) * 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; } }