Hello,

The non-string global-local options (ie, 'autoread' and
'undolevel') don't behave like string ones.
Please find attached a patch fixing this issue.


COMPLETE DESCRIPTION OF THE ISSUE

In the following, 'sglo' represents any string global-local option.

1st inconsistency :
  :setlocal sglo<
    sets the current local value equal to the global one
    (even if the current local value was disabled (empty))
  :set sglo<
    disables the current local value
 whereas
  :setlocal ul</ar<
    disables (sets to -123456 or -1) the current local value
  :set  ul</ar<
    - if the current local value is enabled : sets the current local
      value equal to the global one;
    - otherwise : does nothing.


2nd inconsistency :
 When using “:set” to set/change values (with other
 arguments than {opt}<) :
 - for string G-L options the global value is set to the
   expected value, and the current local value is disabled;
 - for 'ar'/'ul', both the current local value and the global
   value are set to the expected value.

3rd “internal” inconsistency :
* “:set sglo<” is consistent with the description of “:set”
   for string G-L options made in the previous paragraph.
   Indeed, with “:set sglo<” you can think of the mentioned
   “expected value” as the global value itself.
*  On the contrary, “:set” with 'ar'/'ul' isn't consistent (=>
   'ar' and 'ul' don't behave consistently with themselves).
*  Likewise “:setlocal” is consistent for string G-L options
   (whether or not you use the '<' flag) whereas it isn't for
   'ar'/'ul'.


SOLUTION

This simple patch makes 'ar' and 'ul' behave exactly like string
G-L options (no change to the behaviour of string G-L options).

To do so, I thought it was natural to generalize the handling
of boolean G-L options and (separately) of numeric ones (until
now, 'ar' and 'ul' were treated as special cases).
This generalization could ease adding new non-string G-L
options and making existing non-string non-G-L options
global-local as suggests the todo list.
The list mentions 'beval', 'ignorecase' and 'hkmap' which are
boolean, and 'scrolloff'/'sidescrolloff' which are/would be numeric.


Arnaud

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff --git a/src/buffer.c b/src/buffer.c
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2000,7 +2000,7 @@
     clear_string_option(&buf->b_p_qe);
 #endif
     buf->b_p_ar = -1;
-    buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
+    buf->b_p_ul = DISABLED_NUMERIC_VALUE;
 #ifdef FEAT_LISP
     clear_string_option(&buf->b_p_lw);
 #endif
diff --git a/src/option.c b/src/option.c
--- a/src/option.c
+++ b/src/option.c
@@ -3367,7 +3367,7 @@
 
     curbuf->b_p_initialized = TRUE;
     curbuf->b_p_ar = -1;       /* no local 'autoread' value */
-    curbuf->b_p_ul = NO_LOCAL_UNDOLEVEL;
+    curbuf->b_p_ul = DISABLED_NUMERIC_VALUE;
     check_buf_options(curbuf);
     check_win_options(curwin);
     check_options();
@@ -4474,6 +4474,13 @@
                        goto skip;
                    }
 
+                   /* When using ":set opt=val" for a global option
+                    * with a local value the local value will be
+                    * reset, use the global value here. */
+                   if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
+                           && ((int)options[opt_idx].indir & PV_BOTH))
+                       varp = options[opt_idx].var;
+                   
                    /*
                     * ":set opt!": invert
                     * ":set opt&": reset to default value
@@ -4486,15 +4493,8 @@
                                                ((flags & P_VI_DEF) || cp_val)
                                                 ?  VI_DEFAULT : VIM_DEFAULT];
                    else if (nextchar == '<')
-                   {
-                       /* For 'autoread' -1 means to use global value. */
-                       if ((int *)varp == &curbuf->b_p_ar
-                                                   && opt_flags == OPT_LOCAL)
-                           value = -1;
-                       else
-                           value = *(int *)get_varp_scope(&(options[opt_idx]),
+                       value = *(int *)get_varp_scope(&(options[opt_idx]),
                                                                  OPT_GLOBAL);
-                   }
                    else
                    {
                        /*
@@ -4535,22 +4535,22 @@
                         * [-]0-9   set number
                         * other    error
                         */
+                           
+                       /* When using ":set opt=val" for a global option
+                        * with a local value the local value will be
+                        * reset, use the global value here. */
+                       if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
+                               && ((int)options[opt_idx].indir & PV_BOTH))
+                           varp = options[opt_idx].var;
+
                        ++arg;
                        if (nextchar == '&')
                            value = (long)(long_i)options[opt_idx].def_val[
                                                ((flags & P_VI_DEF) || cp_val)
                                                 ?  VI_DEFAULT : VIM_DEFAULT];
                        else if (nextchar == '<')
-                       {
-                           /* For 'undolevels' NO_LOCAL_UNDOLEVEL means to
-                            * use the global value. */
-                           if ((long *)varp == &curbuf->b_p_ul
-                                                   && opt_flags == OPT_LOCAL)
-                               value = NO_LOCAL_UNDOLEVEL;
-                           else
-                               value = *(long *)get_varp_scope(
+                           value = *(long *)get_varp_scope(
                                             &(options[opt_idx]), OPT_GLOBAL);
-                       }
                        else if (((long *)varp == &p_wc
                                    || (long *)varp == &p_wcm)
                                && (*arg == '<'
@@ -7777,8 +7777,14 @@
     need_mouse_correct = TRUE;
 #endif
 
+    /* global option with local value set to use global value; 
+     * disable the local value */
+    if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
+           && ((int)options[opt_idx].indir & PV_BOTH))
+       *(int *)get_varp_scope(&(options[opt_idx]), OPT_LOCAL) = -1;
+
     /* May set global value for local option. */
-    if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
+    else if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
        *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = value;
 
     /*
@@ -8848,8 +8854,14 @@
        p_ss = 0;
     }
 
+    /* global option with local value set to use global value;
+     * disable the local value */
+    if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
+           && ((int)options[opt_idx].indir & PV_BOTH))
+       *(long *)get_varp_scope(&(options[opt_idx]), OPT_LOCAL) = 
DISABLED_NUMERIC_VALUE;
+
     /* May set global value for local option. */
-    if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0)
+    else if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) 
        *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = *pp;
 
     options[opt_idx].flags |= P_WAS_SET;
@@ -10057,7 +10069,7 @@
            break;
 #endif
        case PV_UL:
-           buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
+           buf->b_p_ul = DISABLED_NUMERIC_VALUE;
            break;
 #ifdef FEAT_LISP
        case PV_LW:
@@ -10183,7 +10195,7 @@
        case PV_STL:    return *curwin->w_p_stl != NUL
                                    ? (char_u *)&(curwin->w_p_stl) : p->var;
 #endif
-       case PV_UL:     return curbuf->b_p_ul != NO_LOCAL_UNDOLEVEL
+       case PV_UL:     return curbuf->b_p_ul != DISABLED_NUMERIC_VALUE
                                    ? (char_u *)&(curbuf->b_p_ul) : p->var;
 #ifdef FEAT_LISP
        case PV_LW:     return *curbuf->b_p_lw != NUL
@@ -10743,7 +10755,7 @@
            /* options that are normally global but also have a local value
             * are not copied, start using the global value */
            buf->b_p_ar = -1;
-           buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
+           buf->b_p_ul = DISABLED_NUMERIC_VALUE;
            buf->b_p_bkc = empty_option;
            buf->b_bkc_flags = 0;
 #ifdef FEAT_QUICKFIX
diff --git a/src/option.h b/src/option.h
--- a/src/option.h
+++ b/src/option.h
@@ -1154,4 +1154,4 @@
 };
 
 /* Value for b_p_ul indicating the global value must be used. */
-#define NO_LOCAL_UNDOLEVEL -123456
+#define DISABLED_NUMERIC_VALUE -123456
diff --git a/src/undo.c b/src/undo.c
--- a/src/undo.c
+++ b/src/undo.c
@@ -367,7 +367,7 @@
     static long
 get_undolevel()
 {
-    if (curbuf->b_p_ul == NO_LOCAL_UNDOLEVEL)
+    if (curbuf->b_p_ul == DISABLED_NUMERIC_VALUE)
        return p_ul;
     return curbuf->b_p_ul;
 }

Raspunde prin e-mail lui