forked from aniani/vim
updated for version 7.4.446
Problem: In some situations, when setting up an environment to trigger an autocommand, the environment is not properly restored. Solution: Check the return value of switch_win() and call restore_win() always. (Daniel Hahler)
This commit is contained in:
93
src/eval.c
93
src/eval.c
@@ -12086,15 +12086,17 @@ f_gettabvar(argvars, rettv)
|
|||||||
{
|
{
|
||||||
/* Set tp to be our tabpage, temporarily. Also set the window to the
|
/* Set tp to be our tabpage, temporarily. Also set the window to the
|
||||||
* first window in the tabpage, otherwise the window is not valid. */
|
* first window in the tabpage, otherwise the window is not valid. */
|
||||||
switch_win(&oldcurwin, &oldtabpage, tp->tp_firstwin, tp, TRUE);
|
if (switch_win(&oldcurwin, &oldtabpage, tp->tp_firstwin, tp, TRUE)
|
||||||
|
== OK)
|
||||||
/* look up the variable */
|
|
||||||
/* Let gettabvar({nr}, "") return the "t:" dictionary. */
|
|
||||||
v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', varname, FALSE);
|
|
||||||
if (v != NULL)
|
|
||||||
{
|
{
|
||||||
copy_tv(&v->di_tv, rettv);
|
/* look up the variable */
|
||||||
done = TRUE;
|
/* Let gettabvar({nr}, "") return the "t:" dictionary. */
|
||||||
|
v = find_var_in_ht(&tp->tp_vars->dv_hashtab, 't', varname, FALSE);
|
||||||
|
if (v != NULL)
|
||||||
|
{
|
||||||
|
copy_tv(&v->di_tv, rettv);
|
||||||
|
done = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* restore previous notion of curwin */
|
/* restore previous notion of curwin */
|
||||||
@@ -12233,22 +12235,24 @@ getwinvar(argvars, rettv, off)
|
|||||||
{
|
{
|
||||||
/* Set curwin to be our win, temporarily. Also set the tabpage,
|
/* Set curwin to be our win, temporarily. Also set the tabpage,
|
||||||
* otherwise the window is not valid. */
|
* otherwise the window is not valid. */
|
||||||
switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE);
|
if (switch_win(&oldcurwin, &oldtabpage, win, tp, TRUE) == OK)
|
||||||
|
|
||||||
if (*varname == '&') /* window-local-option */
|
|
||||||
{
|
{
|
||||||
if (get_option_tv(&varname, rettv, 1) == OK)
|
if (*varname == '&') /* window-local-option */
|
||||||
done = TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Look up the variable. */
|
|
||||||
/* Let getwinvar({nr}, "") return the "w:" dictionary. */
|
|
||||||
v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w', varname, FALSE);
|
|
||||||
if (v != NULL)
|
|
||||||
{
|
{
|
||||||
copy_tv(&v->di_tv, rettv);
|
if (get_option_tv(&varname, rettv, 1) == OK)
|
||||||
done = TRUE;
|
done = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Look up the variable. */
|
||||||
|
/* Let getwinvar({nr}, "") return the "w:" dictionary. */
|
||||||
|
v = find_var_in_ht(&win->w_vars->dv_hashtab, 'w',
|
||||||
|
varname, FALSE);
|
||||||
|
if (v != NULL)
|
||||||
|
{
|
||||||
|
copy_tv(&v->di_tv, rettv);
|
||||||
|
done = TRUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17252,34 +17256,33 @@ setwinvar(argvars, rettv, off)
|
|||||||
if (win != NULL && varname != NULL && varp != NULL)
|
if (win != NULL && varname != NULL && varp != NULL)
|
||||||
{
|
{
|
||||||
#ifdef FEAT_WINDOWS
|
#ifdef FEAT_WINDOWS
|
||||||
if (switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == FAIL)
|
if (switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == OK)
|
||||||
return;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (*varname == '&')
|
|
||||||
{
|
{
|
||||||
long numval;
|
if (*varname == '&')
|
||||||
char_u *strval;
|
|
||||||
int error = FALSE;
|
|
||||||
|
|
||||||
++varname;
|
|
||||||
numval = get_tv_number_chk(varp, &error);
|
|
||||||
strval = get_tv_string_buf_chk(varp, nbuf);
|
|
||||||
if (!error && strval != NULL)
|
|
||||||
set_option_value(varname, numval, strval, OPT_LOCAL);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
winvarname = alloc((unsigned)STRLEN(varname) + 3);
|
|
||||||
if (winvarname != NULL)
|
|
||||||
{
|
{
|
||||||
STRCPY(winvarname, "w:");
|
long numval;
|
||||||
STRCPY(winvarname + 2, varname);
|
char_u *strval;
|
||||||
set_var(winvarname, varp, TRUE);
|
int error = FALSE;
|
||||||
vim_free(winvarname);
|
|
||||||
|
++varname;
|
||||||
|
numval = get_tv_number_chk(varp, &error);
|
||||||
|
strval = get_tv_string_buf_chk(varp, nbuf);
|
||||||
|
if (!error && strval != NULL)
|
||||||
|
set_option_value(varname, numval, strval, OPT_LOCAL);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
winvarname = alloc((unsigned)STRLEN(varname) + 3);
|
||||||
|
if (winvarname != NULL)
|
||||||
|
{
|
||||||
|
STRCPY(winvarname, "w:");
|
||||||
|
STRCPY(winvarname + 2, varname);
|
||||||
|
set_var(winvarname, varp, TRUE);
|
||||||
|
vim_free(winvarname);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FEAT_WINDOWS
|
#ifdef FEAT_WINDOWS
|
||||||
restore_win(save_curwin, save_curtab, TRUE);
|
restore_win(save_curwin, save_curtab, TRUE);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -1040,7 +1040,8 @@ free_all_mem()
|
|||||||
entered = TRUE;
|
entered = TRUE;
|
||||||
|
|
||||||
# ifdef FEAT_AUTOCMD
|
# ifdef FEAT_AUTOCMD
|
||||||
block_autocmds(); /* don't want to trigger autocommands here */
|
/* Don't want to trigger autocommands from here on. */
|
||||||
|
block_autocmds();
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# ifdef FEAT_WINDOWS
|
# ifdef FEAT_WINDOWS
|
||||||
|
@@ -741,6 +741,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
446,
|
||||||
/**/
|
/**/
|
||||||
445,
|
445,
|
||||||
/**/
|
/**/
|
||||||
|
11
src/window.c
11
src/window.c
@@ -1271,7 +1271,7 @@ win_init(newp, oldp, flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Initialize window "newp" from window"old".
|
* Initialize window "newp" from window "old".
|
||||||
* Only the essential things are copied.
|
* Only the essential things are copied.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
@@ -6662,8 +6662,8 @@ restore_snapshot_rec(sn, fr)
|
|||||||
|| defined(PROTO)
|
|| defined(PROTO)
|
||||||
/*
|
/*
|
||||||
* Set "win" to be the curwin and "tp" to be the current tab page.
|
* Set "win" to be the curwin and "tp" to be the current tab page.
|
||||||
* restore_win() MUST be called to undo.
|
* restore_win() MUST be called to undo, also when FAIL is returned.
|
||||||
* No autocommands will be executed.
|
* No autocommands will be executed until restore_win() is called.
|
||||||
* When "no_display" is TRUE the display won't be affected, no redraw is
|
* When "no_display" is TRUE the display won't be affected, no redraw is
|
||||||
* triggered, another tabpage access is limited.
|
* triggered, another tabpage access is limited.
|
||||||
* Returns FAIL if switching to "win" failed.
|
* Returns FAIL if switching to "win" failed.
|
||||||
@@ -6696,12 +6696,7 @@ switch_win(save_curwin, save_curtab, win, tp, no_display)
|
|||||||
goto_tabpage_tp(tp, FALSE, FALSE);
|
goto_tabpage_tp(tp, FALSE, FALSE);
|
||||||
}
|
}
|
||||||
if (!win_valid(win))
|
if (!win_valid(win))
|
||||||
{
|
|
||||||
# ifdef FEAT_AUTOCMD
|
|
||||||
unblock_autocmds();
|
|
||||||
# endif
|
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
|
||||||
curwin = win;
|
curwin = win;
|
||||||
curbuf = curwin->w_buffer;
|
curbuf = curwin->w_buffer;
|
||||||
# endif
|
# endif
|
||||||
|
Reference in New Issue
Block a user