]> granicus.if.org Git - vim/commitdiff
patch 8.1.0445: setting 'term' does not store location for termcap options v8.1.0445
authorBram Moolenaar <Bram@vim.org>
Tue, 2 Oct 2018 12:45:10 +0000 (14:45 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 2 Oct 2018 12:45:10 +0000 (14:45 +0200)
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.

src/option.c
src/proto/option.pro
src/term.c
src/testdir/test_options.vim
src/version.c

index 69e026db2980dcfc4d94a71b63668c52ab419e84..d70dc7b5df14831079ecdeb98e376880dd457644 100644 (file)
@@ -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;
+    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; /* cannot happen: didn't find it! */
+           return opt_idx;
+    return -1; // 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();
 }
index b65cb45bf462226515530b5e05befef1c9c995e9..228036587570d3b9787603bd41f21d87caaf5156 100644 (file)
@@ -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);
index f0958762aa98a3dc9078f397c18acb74dd28bc49..4dfb97e74c367892758f7eddbadb58ca014329d5 100644 (file)
@@ -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);
index f34168228d2a6e63bbe4055cd4bb800a1b4870ee..851da1ed16beec69d774eaa92dbe09e5e3420b83 100644 (file)
@@ -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
index e7ce60450b9126f3f3dae9eeda28f8289d407fd2..f4a463759e0d33d4784bcb0616e48a579a40b138 100644 (file)
@@ -792,6 +792,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    445,
 /**/
     444,
 /**/