mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #12192 from Billy4195/vim-8.2.0629
[RFC] vim-patch:8.2.0629
This commit is contained in:
commit
980b12edba
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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: {
|
||||
|
@ -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++;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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',
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user