aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/option.c76
-rw-r--r--src/nvim/optionstr.c8
2 files changed, 48 insertions, 36 deletions
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 6c869c26f0..077aef052b 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -3717,6 +3717,45 @@ vimoption_T *get_option(int opt_idx)
return &options[opt_idx];
}
+/// Clear an option
+///
+/// The exact semantics of this depend on the option.
+static OptVal clear_optval(const char *name, uint32_t flags, void *varp, buf_T *buf, win_T *win)
+{
+ OptVal v = NIL_OPTVAL;
+
+ // Change the type of the OptVal to the type used by the option so that it can be cleared.
+ // TODO(famiu): Clean up all of this after set_(num|bool|string)_option() is unified.
+
+ if (flags & P_BOOL) {
+ v.type = kOptValTypeBoolean;
+ if ((int *)varp == &buf->b_p_ar) {
+ // TODO(lewis6991): replace this with a more general condition that
+ // indicates we are setting the local value of a global-local option
+ v.data.boolean = kNone;
+ } else {
+ v = get_option_value(name, NULL, OPT_GLOBAL, NULL);
+ }
+ } else if (flags & P_NUM) {
+ v.type = kOptValTypeNumber;
+ if ((long *)varp == &curbuf->b_p_ul) {
+ // The one true special case
+ v.data.number = NO_LOCAL_UNDOLEVEL;
+ } else if ((long *)varp == &win->w_p_so || (long *)varp == &win->w_p_siso) {
+ // TODO(lewis6991): replace this with a more general condition that
+ // indicates we are setting the local value of a global-local option
+ v.data.number = -1;
+ } else {
+ v = get_option_value(name, NULL, OPT_GLOBAL, NULL);
+ }
+ } else if (flags & P_STRING) {
+ v.type = kOptValTypeString;
+ v.data.string.data = NULL;
+ }
+
+ return v;
+}
+
/// Set the value of an option
///
/// @param[in] name Option name.
@@ -3762,20 +3801,8 @@ const char *set_option_value(const char *const name, const OptVal value, int opt
// Copy the value so we can modify the copy.
OptVal v = optval_copy(value);
- // Clear an option. For global-local options clear the local value
- // (the exact semantics of this depend on the option).
- bool clear = v.type == kOptValTypeNil;
-
if (v.type == kOptValTypeNil) {
- // Change the type of the OptVal to the type used by the option so that it can be cleared.
- // TODO(famiu): Clean up all of this after set_(num|bool|string)_option() is unified.
- if (flags & P_BOOL) {
- v.type = kOptValTypeBoolean;
- } else if (flags & P_NUM) {
- v.type = kOptValTypeNumber;
- } else if (flags & P_STRING) {
- v.type = kOptValTypeString;
- }
+ v = clear_optval(name, flags, varp, curbuf, curwin);
} else if (!optval_match_type(v, opt_idx)) {
char *rep = optval_to_cstr(v);
char *valid_types = option_get_valid_types(opt_idx);
@@ -3793,35 +3820,16 @@ const char *set_option_value(const char *const name, const OptVal value, int opt
case kOptValTypeNil:
abort(); // This will never happen.
case kOptValTypeBoolean: {
- if (clear) {
- if ((int *)varp == &curbuf->b_p_ar) {
- v.data.boolean = kNone;
- } else {
- v = get_option_value(name, NULL, OPT_GLOBAL, NULL);
- }
- }
errmsg = set_bool_option(opt_idx, varp, (int)v.data.boolean, opt_flags);
break;
}
case kOptValTypeNumber: {
- if (clear) {
- if ((long *)varp == &curbuf->b_p_ul) {
- v.data.number = NO_LOCAL_UNDOLEVEL;
- } else if ((long *)varp == &curwin->w_p_so || (long *)varp == &curwin->w_p_siso) {
- v.data.number = -1;
- } else {
- v = get_option_value(name, NULL, OPT_GLOBAL, NULL);
- }
- }
errmsg = set_num_option(opt_idx, varp, (long)v.data.number, errbuf, sizeof(errbuf), opt_flags);
break;
}
case kOptValTypeString: {
- const char *s = v.data.string.data;
- if (s == NULL || clear) {
- s = "";
- }
- errmsg = set_string_option(opt_idx, s, opt_flags, &value_checked, errbuf, sizeof(errbuf));
+ errmsg = set_string_option(opt_idx, v.data.string.data, opt_flags, &value_checked, errbuf,
+ sizeof(errbuf));
break;
}
}
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index c0a7bfa3f7..c68ee65fcf 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -429,12 +429,16 @@ void set_string_option_direct_in_buf(buf_T *buf, const char *name, int opt_idx,
/// #OPT_GLOBAL.
///
/// @return NULL on success, an untranslated error message on error.
-const char *set_string_option(const int opt_idx, const char *const value, const int opt_flags,
+const char *set_string_option(const int opt_idx, const char *value, const int opt_flags,
bool *value_checked, char *const errbuf, const size_t errbuflen)
- FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_WARN_UNUSED_RESULT
+ FUNC_ATTR_WARN_UNUSED_RESULT
{
vimoption_T *opt = get_option(opt_idx);
+ if (value == NULL) {
+ value = "";
+ }
+
char **varp = (char **)get_varp_scope(opt, ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
? ((opt->indir & PV_BOTH) ? OPT_GLOBAL : OPT_LOCAL)
: opt_flags));