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' can represent 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;
}