mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-11 15:37:29 +02:00
Merge remote-tracking branch 'vim/master'
This commit is contained in:
@@ -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
|
||||
|
||||
+140
-58
@@ -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
|
||||
|
||||
+32
-30
@@ -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);
|
||||
|
||||
+6
-4
@@ -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;
|
||||
}
|
||||
|
||||
+5
-4
@@ -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);
|
||||
|
||||
+26
-13
@@ -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
|
||||
|
||||
|
||||
+33
-8
@@ -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;
|
||||
}
|
||||
|
||||
+4
-1
@@ -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;
|
||||
}
|
||||
|
||||
+9
-8
@@ -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);
|
||||
|
||||
+30
-14
@@ -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,
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+25
-24
@@ -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;
|
||||
|
||||
|
||||
+5
-1
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
+4
-1
@@ -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;
|
||||
|
||||
+6
-1
@@ -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
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
+40
-8
@@ -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)
|
||||
{
|
||||
|
||||
+1
-1
@@ -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. */
|
||||
|
||||
+7
-2
@@ -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);
|
||||
|
||||
+10
-2
@@ -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;
|
||||
|
||||
+4
-4
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
/**/
|
||||
|
||||
@@ -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
|
||||
|
||||
+10
-7
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user