aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/api/private/helpers.c4
-rw-r--r--src/nvim/eval.c42
-rw-r--r--src/nvim/eval/decode.c12
-rw-r--r--src/nvim/eval/encode.c7
-rw-r--r--src/nvim/eval/encode.h1
-rw-r--r--src/nvim/eval/executor.c4
-rw-r--r--src/nvim/eval/funcs.c35
-rw-r--r--src/nvim/eval/typval.c44
-rw-r--r--src/nvim/eval/typval.h10
-rw-r--r--src/nvim/eval/typval_encode.c.h15
-rw-r--r--src/nvim/ex_getln.c4
-rw-r--r--src/nvim/lua/converter.c8
-rw-r--r--src/nvim/ops.c8
-rw-r--r--src/nvim/popupmnu.c4
-rw-r--r--src/nvim/testdir/test_options.vim15
-rw-r--r--src/nvim/vim.h1
-rw-r--r--test/functional/eval/buf_functions_spec.lua6
-rw-r--r--test/functional/eval/sort_spec.lua3
-rw-r--r--test/functional/eval/uniq_spec.lua2
-rw-r--r--test/unit/eval/helpers.lua12
-rw-r--r--test/unit/eval/typval_spec.lua48
21 files changed, 183 insertions, 102 deletions
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index a458762cc6..f194b6b474 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -1075,8 +1075,8 @@ bool object_to_vim(Object obj, typval_T *tv, Error *err)
break;
case kObjectTypeBoolean:
- tv->v_type = VAR_SPECIAL;
- tv->vval.v_special = obj.data.boolean? kSpecialVarTrue: kSpecialVarFalse;
+ tv->v_type = VAR_BOOL;
+ tv->vval.v_bool = obj.data.boolean? kBoolVarTrue: kBoolVarFalse;
break;
case kObjectTypeBuffer:
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index 5f8f3f96f7..66cd0e09c6 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -213,8 +213,8 @@ static struct vimvar {
VV(VV_ERRORS, "errors", VAR_LIST, 0),
VV(VV_MSGPACK_TYPES, "msgpack_types", VAR_DICT, VV_RO),
VV(VV_EVENT, "event", VAR_DICT, VV_RO),
- VV(VV_FALSE, "false", VAR_SPECIAL, VV_RO),
- VV(VV_TRUE, "true", VAR_SPECIAL, VV_RO),
+ VV(VV_FALSE, "false", VAR_BOOL, VV_RO),
+ VV(VV_TRUE, "true", VAR_BOOL, VV_RO),
VV(VV_NULL, "null", VAR_SPECIAL, VV_RO),
VV(VV__NULL_LIST, "_null_list", VAR_LIST, VV_RO),
VV(VV__NULL_DICT, "_null_dict", VAR_DICT, VV_RO),
@@ -237,6 +237,7 @@ static struct vimvar {
// shorthand
#define vv_type vv_di.di_tv.v_type
#define vv_nr vv_di.di_tv.vval.v_number
+#define vv_bool vv_di.di_tv.vval.v_bool
#define vv_special vv_di.di_tv.vval.v_special
#define vv_float vv_di.di_tv.vval.v_float
#define vv_str vv_di.di_tv.vval.v_string
@@ -388,8 +389,8 @@ void eval_init(void)
set_vim_var_nr(VV_TYPE_FLOAT, VAR_TYPE_FLOAT);
set_vim_var_nr(VV_TYPE_BOOL, VAR_TYPE_BOOL);
- set_vim_var_special(VV_FALSE, kSpecialVarFalse);
- set_vim_var_special(VV_TRUE, kSpecialVarTrue);
+ set_vim_var_bool(VV_FALSE, kBoolVarFalse);
+ set_vim_var_bool(VV_TRUE, kBoolVarTrue);
set_vim_var_special(VV_NULL, kSpecialVarNull);
set_vim_var_special(VV_EXITING, kSpecialVarNull);
@@ -1837,12 +1838,15 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
int opt_type;
long numval;
char *stringval = NULL;
+ const char *s = NULL;
const char c1 = *p;
*p = NUL;
varnumber_T n = tv_get_number(tv);
- const char *s = tv_get_string_chk(tv); // != NULL if number or string.
+ if (tv->v_type != VAR_BOOL && tv->v_type != VAR_SPECIAL) {
+ s = tv_get_string_chk(tv); // != NULL if number or string.
+ }
if (s != NULL && op != NULL && *op != '=') {
opt_type = get_option_value(arg, &numval, (char_u **)&stringval,
opt_flags);
@@ -1868,7 +1872,8 @@ static char_u *ex_let_one(char_u *arg, typval_T *const tv,
}
}
}
- if (s != NULL) {
+ if (s != NULL || tv->v_type == VAR_BOOL
+ || tv->v_type == VAR_SPECIAL) {
set_option_value((const char *)arg, n, s, opt_flags);
arg_end = (char_u *)p;
}
@@ -4199,6 +4204,7 @@ eval_index(
}
return FAIL;
}
+ case VAR_BOOL:
case VAR_SPECIAL: {
if (verbose) {
EMSG(_("E909: Cannot index a special variable"));
@@ -4420,6 +4426,7 @@ eval_index(
*rettv = var1;
break;
}
+ case VAR_BOOL:
case VAR_SPECIAL:
case VAR_FUNC:
case VAR_FLOAT:
@@ -5273,6 +5280,7 @@ bool set_ref_in_item(typval_T *tv, int copyID, ht_stack_T **ht_stack,
abort = set_ref_in_func(tv->vval.v_string, NULL, copyID);
break;
case VAR_UNKNOWN:
+ case VAR_BOOL:
case VAR_SPECIAL:
case VAR_FLOAT:
case VAR_NUMBER:
@@ -5743,11 +5751,11 @@ int assert_bool(typval_T *argvars, bool is_true)
if ((argvars[0].v_type != VAR_NUMBER
|| (tv_get_number_chk(&argvars[0], &error) == 0) == is_true
|| error)
- && (argvars[0].v_type != VAR_SPECIAL
- || (argvars[0].vval.v_special
- != (SpecialVarValue) (is_true
- ? kSpecialVarTrue
- : kSpecialVarFalse)))) {
+ && (argvars[0].v_type != VAR_BOOL
+ || (argvars[0].vval.v_bool
+ != (BoolVarValue)(is_true
+ ? kBoolVarTrue
+ : kBoolVarFalse)))) {
prepare_assert_error(&ga);
fill_assert_error(&ga, &argvars[1],
(char_u *)(is_true ? "True" : "False"),
@@ -8049,6 +8057,17 @@ void set_vim_var_nr(const VimVarIndex idx, const varnumber_T val)
vimvars[idx].vv_nr = val;
}
+/// Set boolean v: {true, false} to the given value
+///
+/// @param[in] idx Index of variable to set.
+/// @param[in] val Value to set to.
+void set_vim_var_bool(const VimVarIndex idx, const BoolVarValue val)
+{
+ tv_clear(&vimvars[idx].vv_tv);
+ vimvars[idx].vv_type = VAR_BOOL;
+ vimvars[idx].vv_bool = val;
+}
+
/// Set special v: variable to the given value
///
/// @param[in] idx Index of variable to set.
@@ -9143,6 +9162,7 @@ int var_item_copy(const vimconv_T *const conv,
case VAR_FLOAT:
case VAR_FUNC:
case VAR_PARTIAL:
+ case VAR_BOOL:
case VAR_SPECIAL:
tv_copy(from, to);
break;
diff --git a/src/nvim/eval/decode.c b/src/nvim/eval/decode.c
index 42999ddd62..daba304f00 100644
--- a/src/nvim/eval/decode.c
+++ b/src/nvim/eval/decode.c
@@ -795,9 +795,9 @@ json_decode_string_cycle_start:
}
p += 3;
POP(((typval_T) {
- .v_type = VAR_SPECIAL,
+ .v_type = VAR_BOOL,
.v_lock = VAR_UNLOCKED,
- .vval = { .v_special = kSpecialVarTrue },
+ .vval = { .v_bool = kBoolVarTrue },
}), false);
break;
}
@@ -808,9 +808,9 @@ json_decode_string_cycle_start:
}
p += 4;
POP(((typval_T) {
- .v_type = VAR_SPECIAL,
+ .v_type = VAR_BOOL,
.v_lock = VAR_UNLOCKED,
- .vval = { .v_special = kSpecialVarFalse },
+ .vval = { .v_bool = kBoolVarFalse },
}), false);
break;
}
@@ -954,10 +954,10 @@ int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv)
}
case MSGPACK_OBJECT_BOOLEAN: {
*rettv = (typval_T) {
- .v_type = VAR_SPECIAL,
+ .v_type = VAR_BOOL,
.v_lock = VAR_UNLOCKED,
.vval = {
- .v_special = mobj.via.boolean ? kSpecialVarTrue : kSpecialVarFalse
+ .v_bool = mobj.via.boolean ? kBoolVarTrue : kBoolVarFalse
},
};
break;
diff --git a/src/nvim/eval/encode.c b/src/nvim/eval/encode.c
index 138f638eb2..137f099df6 100644
--- a/src/nvim/eval/encode.c
+++ b/src/nvim/eval/encode.c
@@ -34,10 +34,13 @@
#define utf_ptr2len(b) ((size_t)utf_ptr2len((char_u *)b))
#define utf_char2len(b) ((size_t)utf_char2len(b))
+const char *const encode_bool_var_names[] = {
+ [kBoolVarTrue] = "true",
+ [kBoolVarFalse] = "false",
+};
+
const char *const encode_special_var_names[] = {
[kSpecialVarNull] = "null",
- [kSpecialVarTrue] = "true",
- [kSpecialVarFalse] = "false",
};
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/eval/encode.h b/src/nvim/eval/encode.h
index ccea245ab3..596bb49ae0 100644
--- a/src/nvim/eval/encode.h
+++ b/src/nvim/eval/encode.h
@@ -55,6 +55,7 @@ static inline ListReaderState encode_init_lrstate(const list_T *const list)
}
/// Array mapping values from SpecialVarValue enum to names
+extern const char *const encode_bool_var_names[];
extern const char *const encode_special_var_names[];
/// First codepoint in high surrogates block
diff --git a/src/nvim/eval/executor.c b/src/nvim/eval/executor.c
index 8cd21f8d62..da05ecda43 100644
--- a/src/nvim/eval/executor.c
+++ b/src/nvim/eval/executor.c
@@ -28,11 +28,13 @@ int eexe_mod_op(typval_T *const tv1, const typval_T *const tv2,
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_NO_SANITIZE_UNDEFINED
{
// Can't do anything with a Funcref, a Dict or special value on the right.
- if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT) {
+ if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT
+ && tv2->v_type != VAR_BOOL && tv2->v_type != VAR_SPECIAL) {
switch (tv1->v_type) {
case VAR_DICT:
case VAR_FUNC:
case VAR_PARTIAL:
+ case VAR_BOOL:
case VAR_SPECIAL: {
break;
}
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 25beb4be50..4526eecaba 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -175,8 +175,8 @@ static int non_zero_arg(typval_T *argvars)
{
return ((argvars[0].v_type == VAR_NUMBER
&& argvars[0].vval.v_number != 0)
- || (argvars[0].v_type == VAR_SPECIAL
- && argvars[0].vval.v_special == kSpecialVarTrue)
+ || (argvars[0].v_type == VAR_BOOL
+ && argvars[0].vval.v_bool == kBoolVarTrue)
|| (argvars[0].v_type == VAR_STRING
&& argvars[0].vval.v_string != NULL
&& *argvars[0].vval.v_string != NUL));
@@ -1758,21 +1758,23 @@ static void f_empty(typval_T *argvars, typval_T *rettv, FunPtr fptr)
n = (tv_dict_len(argvars[0].vval.v_dict) == 0);
break;
}
- case VAR_SPECIAL: {
- // Using switch to get warning if SpecialVarValue receives more values.
- switch (argvars[0].vval.v_special) {
- case kSpecialVarTrue: {
+ case VAR_BOOL: {
+ switch (argvars[0].vval.v_bool) {
+ case kBoolVarTrue: {
n = false;
break;
}
- case kSpecialVarFalse:
- case kSpecialVarNull: {
+ case kBoolVarFalse: {
n = true;
break;
}
}
break;
}
+ case VAR_SPECIAL: {
+ n = argvars[0].vval.v_special == kSpecialVarNull;
+ break;
+ }
case VAR_UNKNOWN: {
internal_error("f_empty(UNKNOWN)");
break;
@@ -5189,6 +5191,7 @@ static void f_len(typval_T *argvars, typval_T *rettv, FunPtr fptr)
break;
}
case VAR_UNKNOWN:
+ case VAR_BOOL:
case VAR_SPECIAL:
case VAR_FLOAT:
case VAR_PARTIAL:
@@ -10808,20 +10811,8 @@ static void f_type(typval_T *argvars, typval_T *rettv, FunPtr fptr)
case VAR_LIST: n = VAR_TYPE_LIST; break;
case VAR_DICT: n = VAR_TYPE_DICT; break;
case VAR_FLOAT: n = VAR_TYPE_FLOAT; break;
- case VAR_SPECIAL: {
- switch (argvars[0].vval.v_special) {
- case kSpecialVarTrue:
- case kSpecialVarFalse: {
- n = VAR_TYPE_BOOL;
- break;
- }
- case kSpecialVarNull: {
- n = 7;
- break;
- }
- }
- break;
- }
+ case VAR_BOOL: n = VAR_TYPE_BOOL; break;
+ case VAR_SPECIAL:n = VAR_TYPE_SPECIAL; break;
case VAR_UNKNOWN: {
internal_error("f_type(UNKNOWN)");
break;
diff --git a/src/nvim/eval/typval.c b/src/nvim/eval/typval.c
index 35130f6f40..0daaf6c878 100644
--- a/src/nvim/eval/typval.c
+++ b/src/nvim/eval/typval.c
@@ -1693,21 +1693,21 @@ int tv_dict_add_float(dict_T *const d, const char *const key,
return OK;
}
-/// Add a special entry to dictionary
+/// Add a boolean entry to dictionary
///
/// @param[out] d Dictionary to add entry to.
/// @param[in] key Key to add.
/// @param[in] key_len Key length.
-/// @param[in] val SpecialVarValue to add.
+/// @param[in] val BoolVarValue to add.
///
/// @return OK in case of success, FAIL when key already exists.
-int tv_dict_add_special(dict_T *const d, const char *const key,
- const size_t key_len, SpecialVarValue val)
+int tv_dict_add_bool(dict_T *const d, const char *const key,
+ const size_t key_len, BoolVarValue val)
{
dictitem_T *const item = tv_dict_item_alloc_len(key, key_len);
- item->di_tv.v_type = VAR_SPECIAL;
- item->di_tv.vval.v_special = val;
+ item->di_tv.v_type = VAR_BOOL;
+ item->di_tv.vval.v_bool = val;
if (tv_dict_add(d, item) == FAIL) {
tv_dict_item_free(item);
return FAIL;
@@ -2013,12 +2013,15 @@ void tv_dict_alloc_ret(typval_T *const ret_tv)
#define TYPVAL_ENCODE_CONV_NIL(tv) \
do { \
- tv->vval.v_special = kSpecialVarFalse; \
+ tv->vval.v_special = kSpecialVarNull; \
tv->v_lock = VAR_UNLOCKED; \
} while (0)
#define TYPVAL_ENCODE_CONV_BOOL(tv, num) \
- TYPVAL_ENCODE_CONV_NIL(tv)
+ do { \
+ tv->vval.v_bool = kBoolVarFalse; \
+ tv->v_lock = VAR_UNLOCKED; \
+ } while (0)
#define TYPVAL_ENCODE_CONV_NUMBER(tv, num) \
do { \
@@ -2293,6 +2296,7 @@ void tv_free(typval_T *tv)
tv_dict_unref(tv->vval.v_dict);
break;
}
+ case VAR_BOOL:
case VAR_SPECIAL:
case VAR_NUMBER:
case VAR_FLOAT:
@@ -2324,6 +2328,7 @@ void tv_copy(const typval_T *const from, typval_T *const to)
switch (from->v_type) {
case VAR_NUMBER:
case VAR_FLOAT:
+ case VAR_BOOL:
case VAR_SPECIAL: {
break;
}
@@ -2425,6 +2430,7 @@ void tv_item_lock(typval_T *const tv, const int deep, const bool lock)
case VAR_STRING:
case VAR_FUNC:
case VAR_PARTIAL:
+ case VAR_BOOL:
case VAR_SPECIAL: {
break;
}
@@ -2588,6 +2594,9 @@ bool tv_equal(typval_T *const tv1, typval_T *const tv2, const bool ic,
const char *s2 = tv_get_string_buf(tv2, buf2);
return mb_strcmp_ic((bool)ic, s1, s2) == 0;
}
+ case VAR_BOOL: {
+ return tv1->vval.v_bool == tv2->vval.v_bool;
+ }
case VAR_SPECIAL: {
return tv1->vval.v_special == tv2->vval.v_special;
}
@@ -2638,6 +2647,10 @@ bool tv_check_str_or_nr(const typval_T *const tv)
EMSG(_("E728: Expected a Number or a String, Dictionary found"));
return false;
}
+ case VAR_BOOL: {
+ EMSG(_("E5299: Expected a Number or a String, Boolean found"));
+ return false;
+ }
case VAR_SPECIAL: {
EMSG(_("E5300: Expected a Number or a String"));
return false;
@@ -2677,6 +2690,7 @@ bool tv_check_num(const typval_T *const tv)
{
switch (tv->v_type) {
case VAR_NUMBER:
+ case VAR_BOOL:
case VAR_SPECIAL:
case VAR_STRING: {
return true;
@@ -2721,6 +2735,7 @@ bool tv_check_str(const typval_T *const tv)
{
switch (tv->v_type) {
case VAR_NUMBER:
+ case VAR_BOOL:
case VAR_SPECIAL:
case VAR_STRING: {
return true;
@@ -2791,8 +2806,11 @@ varnumber_T tv_get_number_chk(const typval_T *const tv, bool *const ret_error)
}
return n;
}
+ case VAR_BOOL: {
+ return tv->vval.v_bool == kBoolVarTrue ? 1 : 0;
+ }
case VAR_SPECIAL: {
- return tv->vval.v_special == kSpecialVarTrue ? 1 : 0;
+ return 0;
}
case VAR_UNKNOWN: {
emsgf(_(e_intern2), "tv_get_number(UNKNOWN)");
@@ -2860,6 +2878,10 @@ float_T tv_get_float(const typval_T *const tv)
EMSG(_("E894: Using a Dictionary as a Float"));
break;
}
+ case VAR_BOOL: {
+ EMSG(_("E362: Using a boolean value as a Float"));
+ break;
+ }
case VAR_SPECIAL: {
EMSG(_("E907: Using a special value as a Float"));
break;
@@ -2897,6 +2919,10 @@ const char *tv_get_string_buf_chk(const typval_T *const tv, char *const buf)
}
return "";
}
+ case VAR_BOOL: {
+ STRCPY(buf, encode_bool_var_names[tv->vval.v_bool]);
+ return buf;
+ }
case VAR_SPECIAL: {
STRCPY(buf, encode_special_var_names[tv->vval.v_special]);
return buf;
diff --git a/src/nvim/eval/typval.h b/src/nvim/eval/typval.h
index 4390db1b71..343dd205ff 100644
--- a/src/nvim/eval/typval.h
+++ b/src/nvim/eval/typval.h
@@ -91,10 +91,14 @@ typedef struct dict_watcher {
bool busy; // prevent recursion if the dict is changed in the callback
} DictWatcher;
+/// Bool variable values
+typedef enum {
+ kBoolVarFalse, ///< v:false
+ kBoolVarTrue, ///< v:true
+} BoolVarValue;
+
/// Special variable values
typedef enum {
- kSpecialVarFalse, ///< v:false
- kSpecialVarTrue, ///< v:true
kSpecialVarNull, ///< v:null
} SpecialVarValue;
@@ -114,6 +118,7 @@ typedef enum {
VAR_LIST, ///< List, .v_list is used.
VAR_DICT, ///< Dictionary, .v_dict is used.
VAR_FLOAT, ///< Floating-point value, .v_float is used.
+ VAR_BOOL, ///< true, false
VAR_SPECIAL, ///< Special value (true, false, null), .v_special
///< is used.
VAR_PARTIAL, ///< Partial, .v_partial is used.
@@ -125,6 +130,7 @@ typedef struct {
VarLockStatus v_lock; ///< Variable lock status.
union typval_vval_union {
varnumber_T v_number; ///< Number, for VAR_NUMBER.
+ BoolVarValue v_bool; ///< Bool value, for VAR_BOOL
SpecialVarValue v_special; ///< Special value, for VAR_SPECIAL.
float_T v_float; ///< Floating-point number, for VAR_FLOAT.
char_u *v_string; ///< String, for VAR_STRING and VAR_FUNC, can be NULL.
diff --git a/src/nvim/eval/typval_encode.c.h b/src/nvim/eval/typval_encode.c.h
index 94986a64b5..0aa64b1d5f 100644
--- a/src/nvim/eval/typval_encode.c.h
+++ b/src/nvim/eval/typval_encode.c.h
@@ -379,17 +379,22 @@ static int _TYPVAL_ENCODE_CONVERT_ONE_VALUE(
TYPVAL_ENCODE_CONV_REAL_LIST_AFTER_START(tv, _mp_last(*mpstack));
break;
}
+ case VAR_BOOL: {
+ switch (tv->vval.v_bool) {
+ case kBoolVarTrue:
+ case kBoolVarFalse: {
+ TYPVAL_ENCODE_CONV_BOOL(tv, tv->vval.v_bool == kBoolVarTrue);
+ break;
+ }
+ }
+ break;
+ }
case VAR_SPECIAL: {
switch (tv->vval.v_special) {
case kSpecialVarNull: {
TYPVAL_ENCODE_CONV_NIL(tv); // -V1037
break;
}
- case kSpecialVarTrue:
- case kSpecialVarFalse: {
- TYPVAL_ENCODE_CONV_BOOL(tv, tv->vval.v_special == kSpecialVarTrue);
- break;
- }
}
break;
}
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 56a8f56753..1a836b7a98 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -432,8 +432,8 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
tv_dict_add_nr(dict, S_LEN("cmdlevel"), ccline.level);
tv_dict_set_keys_readonly(dict);
// not readonly:
- tv_dict_add_special(dict, S_LEN("abort"),
- s->gotesc ? kSpecialVarTrue : kSpecialVarFalse);
+ tv_dict_add_bool(dict, S_LEN("abort"),
+ s->gotesc ? kBoolVarTrue : kBoolVarFalse);
try_enter(&tstate);
apply_autocmds(EVENT_CMDLINELEAVE, (char_u *)firstcbuf, (char_u *)firstcbuf,
false, curbuf);
diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c
index fca74b5901..69114c967d 100644
--- a/src/nvim/lua/converter.c
+++ b/src/nvim/lua/converter.c
@@ -286,10 +286,10 @@ bool nlua_pop_typval(lua_State *lstate, typval_T *ret_tv)
break;
}
case LUA_TBOOLEAN: {
- cur.tv->v_type = VAR_SPECIAL;
- cur.tv->vval.v_special = (lua_toboolean(lstate, -1)
- ? kSpecialVarTrue
- : kSpecialVarFalse);
+ cur.tv->v_type = VAR_BOOL;
+ cur.tv->vval.v_bool = (lua_toboolean(lstate, -1)
+ ? kBoolVarTrue
+ : kBoolVarFalse);
break;
}
case LUA_TSTRING: {
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index 755c1519fd..eb32a1dd9b 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -2740,8 +2740,8 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
tv_dict_add_str(dict, S_LEN("regname"), buf);
// Motion type: inclusive or exclusive.
- tv_dict_add_special(dict, S_LEN("inclusive"),
- oap->inclusive ? kSpecialVarTrue : kSpecialVarFalse);
+ tv_dict_add_bool(dict, S_LEN("inclusive"),
+ oap->inclusive ? kBoolVarTrue : kBoolVarFalse);
// Kind of operation: yank, delete, change).
buf[0] = (char)get_op_char(oap->op_type);
@@ -2749,8 +2749,8 @@ static void do_autocmd_textyankpost(oparg_T *oap, yankreg_T *reg)
tv_dict_add_str(dict, S_LEN("operator"), buf);
// Selection type: visual or not.
- tv_dict_add_special(dict, S_LEN("visual"),
- oap->is_VIsual ? kSpecialVarTrue : kSpecialVarFalse);
+ tv_dict_add_bool(dict, S_LEN("visual"),
+ oap->is_VIsual ? kBoolVarTrue : kBoolVarFalse);
tv_dict_set_keys_readonly(dict);
textlock++;
diff --git a/src/nvim/popupmnu.c b/src/nvim/popupmnu.c
index e06433892d..c712762bdf 100644
--- a/src/nvim/popupmnu.c
+++ b/src/nvim/popupmnu.c
@@ -923,6 +923,6 @@ void pum_set_event_info(dict_T *dict)
tv_dict_add_float(dict, S_LEN("row"), r);
tv_dict_add_float(dict, S_LEN("col"), c);
tv_dict_add_nr(dict, S_LEN("size"), pum_size);
- tv_dict_add_special(dict, S_LEN("scrollbar"),
- pum_scrollbar ? kSpecialVarTrue : kSpecialVarFalse);
+ tv_dict_add_bool(dict, S_LEN("scrollbar"),
+ pum_scrollbar ? kBoolVarTrue : kBoolVarFalse);
}
diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim
index 400af33c58..04a5c62f66 100644
--- a/src/nvim/testdir/test_options.vim
+++ b/src/nvim/testdir/test_options.vim
@@ -561,3 +561,18 @@ func Test_visualbell()
set novisualbell
set belloff=all
endfunc
+
+" Test for setting option values using v:false and v:true
+func Test_opt_boolean()
+ set number&
+ set number
+ call assert_equal(1, &nu)
+ set nonu
+ call assert_equal(0, &nu)
+ let &nu = v:true
+ call assert_equal(1, &nu)
+ let &nu = v:false
+ call assert_equal(0, &nu)
+ set number&
+endfunc
+
diff --git a/src/nvim/vim.h b/src/nvim/vim.h
index c1eea1ab90..832703e83d 100644
--- a/src/nvim/vim.h
+++ b/src/nvim/vim.h
@@ -101,6 +101,7 @@ typedef enum {
#define VAR_TYPE_DICT 4
#define VAR_TYPE_FLOAT 5
#define VAR_TYPE_BOOL 6
+#define VAR_TYPE_SPECIAL 7
// values for xp_context when doing command line completion
diff --git a/test/functional/eval/buf_functions_spec.lua b/test/functional/eval/buf_functions_spec.lua
index 37f4c89bfd..06841a4521 100644
--- a/test/functional/eval/buf_functions_spec.lua
+++ b/test/functional/eval/buf_functions_spec.lua
@@ -31,10 +31,12 @@ for _, func in ipairs({'bufname(%s)', 'bufnr(%s)', 'bufwinnr(%s)',
it('errors out when receives v:true/v:false/v:null', function()
-- Not compatible with Vim: in Vim it always results in buffer not found
-- without any error messages.
- for _, var in ipairs({'v:true', 'v:false', 'v:null'}) do
- eq('Vim(call):E5300: Expected a Number or a String',
+ for _, var in ipairs({'v:true', 'v:false'}) do
+ eq('Vim(call):E5299: Expected a Number or a String, Boolean found',
exc_exec('call ' .. func:format(var)))
end
+ eq('Vim(call):E5300: Expected a Number or a String',
+ exc_exec('call ' .. func:format('v:null')))
end)
it('errors out when receives invalid argument', function()
eq('Vim(call):E745: Expected a Number or a String, List found',
diff --git a/test/functional/eval/sort_spec.lua b/test/functional/eval/sort_spec.lua
index 82557575ce..e1cc2c2924 100644
--- a/test/functional/eval/sort_spec.lua
+++ b/test/functional/eval/sort_spec.lua
@@ -14,7 +14,7 @@ before_each(clear)
describe('sort()', function()
it('errors out when sorting special values', function()
- eq('Vim(call):E907: Using a special value as a Float',
+ eq('Vim(call):E362: Using a boolean value as a Float',
exc_exec('call sort([v:true, v:false], "f")'))
end)
@@ -30,6 +30,7 @@ describe('sort()', function()
errors[err] = true
end
eq({
+ ['E362: Using a boolean value as a Float']=true,
['E891: Using a Funcref as a Float']=true,
['E892: Using a String as a Float']=true,
['E893: Using a List as a Float']=true,
diff --git a/test/functional/eval/uniq_spec.lua b/test/functional/eval/uniq_spec.lua
index 0e7a013e32..5cdba0a0f6 100644
--- a/test/functional/eval/uniq_spec.lua
+++ b/test/functional/eval/uniq_spec.lua
@@ -11,7 +11,7 @@ before_each(clear)
describe('uniq()', function()
it('errors out when processing special values', function()
- eq('Vim(call):E907: Using a special value as a Float',
+ eq('Vim(call):E362: Using a boolean value as a Float',
exc_exec('call uniq([v:true, v:false], "f")'))
end)
diff --git a/test/unit/eval/helpers.lua b/test/unit/eval/helpers.lua
index bcd7c750c5..b600f01ab2 100644
--- a/test/unit/eval/helpers.lua
+++ b/test/unit/eval/helpers.lua
@@ -136,11 +136,15 @@ local function typvalt2lua_tab_init()
return
end
typvalt2lua_tab = {
+ [tonumber(eval.VAR_BOOL)] = function(t)
+ return ({
+ [tonumber(eval.kBoolVarFalse)] = false,
+ [tonumber(eval.kBoolVarTrue)] = true,
+ })[tonumber(t.vval.v_bool)]
+ end,
[tonumber(eval.VAR_SPECIAL)] = function(t)
return ({
- [tonumber(eval.kSpecialVarFalse)] = false,
[tonumber(eval.kSpecialVarNull)] = nil_value,
- [tonumber(eval.kSpecialVarTrue)] = true,
})[tonumber(t.vval.v_special)]
end,
[tonumber(eval.VAR_NUMBER)] = function(t)
@@ -349,8 +353,8 @@ lua2typvalt = function(l, processed)
[null_list] = {'VAR_LIST', {v_list=ffi.cast('list_T*', nil)}},
[null_dict] = {'VAR_DICT', {v_dict=ffi.cast('dict_T*', nil)}},
[nil_value] = {'VAR_SPECIAL', {v_special=eval.kSpecialVarNull}},
- [true] = {'VAR_SPECIAL', {v_special=eval.kSpecialVarTrue}},
- [false] = {'VAR_SPECIAL', {v_special=eval.kSpecialVarFalse}},
+ [true] = {'VAR_BOOL', {v_bool=eval.kBoolVarTrue}},
+ [false] = {'VAR_BOOL', {v_bool=eval.kBoolVarFalse}},
}
for k, v in pairs(special_vals) do
diff --git a/test/unit/eval/typval_spec.lua b/test/unit/eval/typval_spec.lua
index ea86ccbf1c..06465071c5 100644
--- a/test/unit/eval/typval_spec.lua
+++ b/test/unit/eval/typval_spec.lua
@@ -48,8 +48,7 @@ local lib = cimport('./src/nvim/eval/typval.h', './src/nvim/memory.h',
local function vimconv_alloc()
return ffi.gc(
- ffi.cast('vimconv_T*', lib.xcalloc(1, ffi.sizeof('vimconv_T'))),
- function(vc)
+ ffi.cast('vimconv_T*', lib.xcalloc(1, ffi.sizeof('vimconv_T'))), function(vc)
lib.convert_setup(vc, nil, nil)
lib.xfree(vc)
end)
@@ -2838,6 +2837,7 @@ describe('typval.c', function()
{lib.VAR_FUNC, 'E729: using Funcref as a String'},
{lib.VAR_LIST, 'E730: using List as a String'},
{lib.VAR_DICT, 'E731: using Dictionary as a String'},
+ {lib.VAR_BOOL, nil},
{lib.VAR_SPECIAL, nil},
{lib.VAR_UNKNOWN, 'E908: using an invalid value as a String'},
}) do
@@ -2868,8 +2868,8 @@ describe('typval.c', function()
{lib.VAR_LIST, {v_list=NULL}, 'E745: Using a List as a Number', 0},
{lib.VAR_DICT, {v_dict=NULL}, 'E728: Using a Dictionary as a Number', 0},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarNull}, nil, 0},
- {lib.VAR_SPECIAL, {v_special=lib.kSpecialVarTrue}, nil, 1},
- {lib.VAR_SPECIAL, {v_special=lib.kSpecialVarFalse}, nil, 0},
+ {lib.VAR_BOOL, {v_bool=lib.kBoolVarTrue}, nil, 1},
+ {lib.VAR_BOOL, {v_bool=lib.kBoolVarFalse}, nil, 0},
{lib.VAR_UNKNOWN, nil, 'E685: Internal error: tv_get_number(UNKNOWN)', 0},
}) do
-- Using to_cstr, cannot free with tv_clear
@@ -2897,8 +2897,8 @@ describe('typval.c', function()
{lib.VAR_LIST, {v_list=NULL}, 'E745: Using a List as a Number', 0},
{lib.VAR_DICT, {v_dict=NULL}, 'E728: Using a Dictionary as a Number', 0},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarNull}, nil, 0},
- {lib.VAR_SPECIAL, {v_special=lib.kSpecialVarTrue}, nil, 1},
- {lib.VAR_SPECIAL, {v_special=lib.kSpecialVarFalse}, nil, 0},
+ {lib.VAR_BOOL, {v_bool=lib.kBoolVarTrue}, nil, 1},
+ {lib.VAR_BOOL, {v_bool=lib.kBoolVarFalse}, nil, 0},
{lib.VAR_UNKNOWN, nil, 'E685: Internal error: tv_get_number(UNKNOWN)', 0},
}) do
-- Using to_cstr, cannot free with tv_clear
@@ -2931,8 +2931,8 @@ describe('typval.c', function()
{lib.VAR_LIST, {v_list=NULL}, 'E745: Using a List as a Number', -1},
{lib.VAR_DICT, {v_dict=NULL}, 'E728: Using a Dictionary as a Number', -1},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarNull}, nil, 0},
- {lib.VAR_SPECIAL, {v_special=lib.kSpecialVarTrue}, nil, 1},
- {lib.VAR_SPECIAL, {v_special=lib.kSpecialVarFalse}, nil, 0},
+ {lib.VAR_BOOL, {v_bool=lib.kBoolVarTrue}, nil, 1},
+ {lib.VAR_BOOL, {v_bool=lib.kBoolVarFalse}, nil, 0},
{lib.VAR_UNKNOWN, nil, 'E685: Internal error: tv_get_number(UNKNOWN)', -1},
}) do
lib.curwin.w_cursor.lnum = 46
@@ -2961,8 +2961,8 @@ describe('typval.c', function()
{lib.VAR_LIST, {v_list=NULL}, 'E893: Using a List as a Float', 0},
{lib.VAR_DICT, {v_dict=NULL}, 'E894: Using a Dictionary as a Float', 0},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarNull}, 'E907: Using a special value as a Float', 0},
- {lib.VAR_SPECIAL, {v_special=lib.kSpecialVarTrue}, 'E907: Using a special value as a Float', 0},
- {lib.VAR_SPECIAL, {v_special=lib.kSpecialVarFalse}, 'E907: Using a special value as a Float', 0},
+ {lib.VAR_BOOL, {v_bool=lib.kBoolVarTrue}, 'E362: Using a boolean value as a Float', 0},
+ {lib.VAR_BOOL, {v_bool=lib.kBoolVarFalse}, 'E362: Using a boolean value as a Float', 0},
{lib.VAR_UNKNOWN, nil, 'E685: Internal error: tv_get_float(UNKNOWN)', 0},
}) do
-- Using to_cstr, cannot free with tv_clear
@@ -2993,8 +2993,8 @@ describe('typval.c', function()
{lib.VAR_LIST, {v_list=NULL}, 'E730: using List as a String', ''},
{lib.VAR_DICT, {v_dict=NULL}, 'E731: using Dictionary as a String', ''},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarNull}, nil, 'null'},
- {lib.VAR_SPECIAL, {v_special=lib.kSpecialVarTrue}, nil, 'true'},
- {lib.VAR_SPECIAL, {v_special=lib.kSpecialVarFalse}, nil, 'false'},
+ {lib.VAR_BOOL, {v_bool=lib.kBoolVarTrue}, nil, 'true'},
+ {lib.VAR_BOOL, {v_bool=lib.kBoolVarFalse}, nil, 'false'},
{lib.VAR_UNKNOWN, nil, 'E908: using an invalid value as a String', ''},
}) do
-- Using to_cstr in place of Neovim allocated string, cannot
@@ -3005,7 +3005,8 @@ describe('typval.c', function()
local ret = v[4]
eq(ret, check_emsg(function()
local res = lib.tv_get_string(tv)
- if tv.v_type == lib.VAR_NUMBER or tv.v_type == lib.VAR_SPECIAL then
+ if tv.v_type == lib.VAR_NUMBER or tv.v_type == lib.VAR_SPECIAL
+ or tv.v_type == lib.VAR_BOOL then
eq(buf, res)
else
neq(buf, res)
@@ -3036,8 +3037,8 @@ describe('typval.c', function()
{lib.VAR_LIST, {v_list=NULL}, 'E730: using List as a String', nil},
{lib.VAR_DICT, {v_dict=NULL}, 'E731: using Dictionary as a String', nil},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarNull}, nil, 'null'},
- {lib.VAR_SPECIAL, {v_special=lib.kSpecialVarTrue}, nil, 'true'},
- {lib.VAR_SPECIAL, {v_special=lib.kSpecialVarFalse}, nil, 'false'},
+ {lib.VAR_BOOL, {v_bool=lib.kBoolVarTrue}, nil, 'true'},
+ {lib.VAR_BOOL, {v_bool=lib.kBoolVarFalse}, nil, 'false'},
{lib.VAR_UNKNOWN, nil, 'E908: using an invalid value as a String', nil},
}) do
-- Using to_cstr, cannot free with tv_clear
@@ -3047,7 +3048,8 @@ describe('typval.c', function()
local ret = v[4]
eq(ret, check_emsg(function()
local res = lib.tv_get_string_chk(tv)
- if tv.v_type == lib.VAR_NUMBER or tv.v_type == lib.VAR_SPECIAL then
+ if tv.v_type == lib.VAR_NUMBER or tv.v_type == lib.VAR_SPECIAL
+ or tv.v_type == lib.VAR_BOOL then
eq(buf, res)
else
neq(buf, res)
@@ -3077,8 +3079,8 @@ describe('typval.c', function()
{lib.VAR_LIST, {v_list=NULL}, 'E730: using List as a String', ''},
{lib.VAR_DICT, {v_dict=NULL}, 'E731: using Dictionary as a String', ''},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarNull}, nil, 'null'},
- {lib.VAR_SPECIAL, {v_special=lib.kSpecialVarTrue}, nil, 'true'},
- {lib.VAR_SPECIAL, {v_special=lib.kSpecialVarFalse}, nil, 'false'},
+ {lib.VAR_BOOL, {v_bool=lib.kBoolVarTrue}, nil, 'true'},
+ {lib.VAR_BOOL, {v_bool=lib.kBoolVarFalse}, nil, 'false'},
{lib.VAR_UNKNOWN, nil, 'E908: using an invalid value as a String', ''},
}) do
-- Using to_cstr, cannot free with tv_clear
@@ -3089,7 +3091,8 @@ describe('typval.c', function()
eq(ret, check_emsg(function()
local buf = ffi.new('char[?]', lib.NUMBUFLEN, {0})
local res = lib.tv_get_string_buf(tv, buf)
- if tv.v_type == lib.VAR_NUMBER or tv.v_type == lib.VAR_SPECIAL then
+ if tv.v_type == lib.VAR_NUMBER or tv.v_type == lib.VAR_SPECIAL
+ or tv.v_type == lib.VAR_BOOL then
eq(buf, res)
else
neq(buf, res)
@@ -3119,8 +3122,8 @@ describe('typval.c', function()
{lib.VAR_LIST, {v_list=NULL}, 'E730: using List as a String', nil},
{lib.VAR_DICT, {v_dict=NULL}, 'E731: using Dictionary as a String', nil},
{lib.VAR_SPECIAL, {v_special=lib.kSpecialVarNull}, nil, 'null'},
- {lib.VAR_SPECIAL, {v_special=lib.kSpecialVarTrue}, nil, 'true'},
- {lib.VAR_SPECIAL, {v_special=lib.kSpecialVarFalse}, nil, 'false'},
+ {lib.VAR_BOOL, {v_bool=lib.kBoolVarTrue}, nil, 'true'},
+ {lib.VAR_BOOL, {v_bool=lib.kBoolVarFalse}, nil, 'false'},
{lib.VAR_UNKNOWN, nil, 'E908: using an invalid value as a String', nil},
}) do
-- Using to_cstr, cannot free with tv_clear
@@ -3131,7 +3134,8 @@ describe('typval.c', function()
eq(ret, check_emsg(function()
local buf = ffi.new('char[?]', lib.NUMBUFLEN, {0})
local res = lib.tv_get_string_buf_chk(tv, buf)
- if tv.v_type == lib.VAR_NUMBER or tv.v_type == lib.VAR_SPECIAL then
+ if tv.v_type == lib.VAR_NUMBER or tv.v_type == lib.VAR_SPECIAL
+ or tv.v_type == lib.VAR_BOOL then
eq(buf, res)
else
neq(buf, res)