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 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