forked from aniani/vim
patch 8.1.0445: setting 'term' does not store location for termcap options
Problem: Setting 'term' does not store location for termcap options. Solution: Set the script context for termcap options that are changed when 'term' is set.
This commit is contained in:
64
src/option.c
64
src/option.c
@@ -1755,12 +1755,12 @@ static struct vimoption options[] =
|
||||
{"langmap", "lmap", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP|P_SECURE,
|
||||
#ifdef FEAT_LANGMAP
|
||||
(char_u *)&p_langmap, PV_NONE,
|
||||
{(char_u *)"", /* unmatched } */
|
||||
{(char_u *)"", (char_u *)0L}
|
||||
#else
|
||||
(char_u *)NULL, PV_NONE,
|
||||
{(char_u *)NULL,
|
||||
{(char_u *)NULL, (char_u *)0L}
|
||||
#endif
|
||||
(char_u *)0L} SCTX_INIT},
|
||||
SCTX_INIT},
|
||||
{"langmenu", "lm", P_STRING|P_VI_DEF|P_NFNAME,
|
||||
#if defined(FEAT_MENU) && defined(FEAT_MULTI_LANG)
|
||||
(char_u *)&p_lm, PV_NONE,
|
||||
@@ -5790,20 +5790,32 @@ check_string_option(char_u **pp)
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark a terminal option as allocated, found by a pointer into term_strings[].
|
||||
* Return the option index found by a pointer into term_strings[].
|
||||
* Return -1 if not found.
|
||||
*/
|
||||
void
|
||||
set_term_option_alloced(char_u **p)
|
||||
int
|
||||
get_term_opt_idx(char_u **p)
|
||||
{
|
||||
int opt_idx;
|
||||
|
||||
for (opt_idx = 1; options[opt_idx].fullname != NULL; opt_idx++)
|
||||
if (options[opt_idx].var == (char_u *)p)
|
||||
{
|
||||
options[opt_idx].flags |= P_ALLOCED;
|
||||
return;
|
||||
return opt_idx;
|
||||
return -1; // cannot happen: didn't find it!
|
||||
}
|
||||
return; /* cannot happen: didn't find it! */
|
||||
|
||||
/*
|
||||
* Mark a terminal option as allocated, found by a pointer into term_strings[].
|
||||
* Return the option index or -1 if not found.
|
||||
*/
|
||||
int
|
||||
set_term_option_alloced(char_u **p)
|
||||
{
|
||||
int opt_idx = get_term_opt_idx(p);
|
||||
|
||||
if (opt_idx >= 0)
|
||||
options[opt_idx].flags |= P_ALLOCED;
|
||||
return opt_idx;
|
||||
}
|
||||
|
||||
#if defined(FEAT_EVAL) || defined(PROTO)
|
||||
@@ -8237,6 +8249,32 @@ set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
|
||||
curwin->w_p_script_ctx[indir & PV_MASK] = new_script_ctx;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the script_ctx for a termcap option.
|
||||
* "name" must be the two character code, e.g. "RV".
|
||||
* When "name" is NULL use "opt_idx".
|
||||
*/
|
||||
void
|
||||
set_term_option_sctx_idx(char *name, int opt_idx)
|
||||
{
|
||||
char_u buf[5];
|
||||
int idx;
|
||||
|
||||
if (name == NULL)
|
||||
idx = opt_idx;
|
||||
else
|
||||
{
|
||||
buf[0] = 't';
|
||||
buf[1] = '_';
|
||||
buf[2] = name[0];
|
||||
buf[3] = name[1];
|
||||
buf[4] = 0;
|
||||
idx = findoption(buf);
|
||||
}
|
||||
if (idx >= 0)
|
||||
set_option_sctx_idx(idx, OPT_GLOBAL, current_sctx);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -10445,7 +10483,7 @@ free_termoptions(void)
|
||||
{
|
||||
struct vimoption *p;
|
||||
|
||||
for (p = &options[0]; p->fullname != NULL; p++)
|
||||
for (p = options; p->fullname != NULL; p++)
|
||||
if (istermoption(p))
|
||||
{
|
||||
if (p->flags & P_ALLOCED)
|
||||
@@ -10455,6 +10493,10 @@ free_termoptions(void)
|
||||
*(char_u **)(p->var) = empty_option;
|
||||
p->def_val[VI_DEFAULT] = empty_option;
|
||||
p->flags &= ~(P_ALLOCED|P_DEF_ALLOCED);
|
||||
#ifdef FEAT_EVAL
|
||||
// remember where the option was cleared
|
||||
set_option_sctx_idx((int)(p - options), OPT_GLOBAL, current_sctx);
|
||||
#endif
|
||||
}
|
||||
clear_termcodes();
|
||||
}
|
||||
|
@@ -17,11 +17,13 @@ void check_options(void);
|
||||
void check_buf_options(buf_T *buf);
|
||||
void free_string_option(char_u *p);
|
||||
void clear_string_option(char_u **pp);
|
||||
void set_term_option_alloced(char_u **p);
|
||||
int get_term_opt_idx(char_u **p);
|
||||
int set_term_option_alloced(char_u **p);
|
||||
int was_set_insecurely(char_u *opt, int opt_flags);
|
||||
void set_string_option_direct(char_u *name, int opt_idx, char_u *val, int opt_flags, int set_sid);
|
||||
char_u *check_colorcolumn(win_T *wp);
|
||||
char_u *check_stl_option(char_u *s);
|
||||
void set_term_option_sctx_idx(char *name, int opt_idx);
|
||||
int get_option_value(char_u *name, long *numval, char_u **stringval, int opt_flags);
|
||||
int get_option_value_strict(char_u *name, long *numval, char_u **stringval, int opt_type, void *from);
|
||||
char_u *option_iter_next(void **option, int opt_type);
|
||||
|
27
src/term.c
27
src/term.c
@@ -1471,6 +1471,9 @@ parse_builtin_tcap(char_u *term)
|
||||
if (term_strings[p->bt_entry] == NULL
|
||||
|| term_strings[p->bt_entry] == empty_option)
|
||||
{
|
||||
#ifdef FEAT_EVAL
|
||||
int opt_idx = -1;
|
||||
#endif
|
||||
/* 8bit terminal: use CSI instead of <Esc>[ */
|
||||
if (term_8bit && term_7to8bit((char_u *)p->bt_string) != 0)
|
||||
{
|
||||
@@ -1486,11 +1489,23 @@ parse_builtin_tcap(char_u *term)
|
||||
STRMOVE(t + 1, t + 2);
|
||||
}
|
||||
term_strings[p->bt_entry] = s;
|
||||
set_term_option_alloced(&term_strings[p->bt_entry]);
|
||||
#ifdef FEAT_EVAL
|
||||
opt_idx =
|
||||
#endif
|
||||
set_term_option_alloced(
|
||||
&term_strings[p->bt_entry]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
term_strings[p->bt_entry] = (char_u *)p->bt_string;
|
||||
#ifdef FEAT_EVAL
|
||||
opt_idx = get_term_opt_idx(&term_strings[p->bt_entry]);
|
||||
#endif
|
||||
}
|
||||
#ifdef FEAT_EVAL
|
||||
set_term_option_sctx_idx(NULL, opt_idx);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1616,7 +1631,12 @@ get_term_entries(int *height, int *width)
|
||||
{
|
||||
if (TERM_STR(string_names[i].dest) == NULL
|
||||
|| TERM_STR(string_names[i].dest) == empty_option)
|
||||
{
|
||||
TERM_STR(string_names[i].dest) = TGETSTR(string_names[i].name, &tp);
|
||||
#ifdef FEAT_EVAL
|
||||
set_term_option_sctx_idx(string_names[i].name, -1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* tgetflag() returns 1 if the flag is present, 0 if not and
|
||||
@@ -1658,7 +1678,12 @@ get_term_entries(int *height, int *width)
|
||||
* Get number of colors (if not done already).
|
||||
*/
|
||||
if (TERM_STR(KS_CCO) == NULL || TERM_STR(KS_CCO) == empty_option)
|
||||
{
|
||||
set_color_count(tgetnum("Co"));
|
||||
#ifdef FEAT_EVAL
|
||||
set_term_option_sctx_idx("Co", -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
# ifndef hpux
|
||||
BC = (char *)TGETSTR("bc", &tp);
|
||||
|
@@ -270,6 +270,18 @@ func Test_set_errors()
|
||||
call assert_fails('set t_foo=', 'E846:')
|
||||
endfunc
|
||||
|
||||
" Must be executed before other tests that set 'term'.
|
||||
func Test_000_term_option_verbose()
|
||||
let verb_cm = execute('verbose set t_cm')
|
||||
call assert_notmatch('Last set from', verb_cm)
|
||||
|
||||
let term_save = &term
|
||||
set term=ansi
|
||||
let verb_cm = execute('verbose set t_cm')
|
||||
call assert_match('Last set from.*test_options.vim', verb_cm)
|
||||
let &term = term_save
|
||||
endfunc
|
||||
|
||||
func Test_set_ttytype()
|
||||
if !has('gui_running') && has('unix')
|
||||
" Setting 'ttytype' used to cause a double-free when exiting vim and
|
||||
|
@@ -792,6 +792,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
445,
|
||||
/**/
|
||||
444,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user