forked from aniani/vim
patch 8.2.2254: Vim9: bool option type is number
Problem: Vim9: bool option type is number. Solution: Have get_option_value() return a different value for bool and number options. (closes #7583)
This commit is contained in:
parent
ca2f7e7af3
commit
dd1f426bd6
@ -1354,7 +1354,7 @@ ex_let_one(
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
long n = 0;
|
long n = 0;
|
||||||
int opt_type;
|
getoption_T opt_type;
|
||||||
long numval;
|
long numval;
|
||||||
char_u *stringval = NULL;
|
char_u *stringval = NULL;
|
||||||
char_u *s = NULL;
|
char_u *s = NULL;
|
||||||
@ -1364,7 +1364,10 @@ ex_let_one(
|
|||||||
*p = NUL;
|
*p = NUL;
|
||||||
|
|
||||||
opt_type = get_option_value(arg, &numval, &stringval, opt_flags);
|
opt_type = get_option_value(arg, &numval, &stringval, opt_flags);
|
||||||
if ((opt_type == 1 || opt_type == -1)
|
if ((opt_type == gov_bool
|
||||||
|
|| opt_type == gov_number
|
||||||
|
|| opt_type == gov_hidden_bool
|
||||||
|
|| opt_type == gov_hidden_number)
|
||||||
&& (tv->v_type != VAR_STRING || !in_vim9script()))
|
&& (tv->v_type != VAR_STRING || !in_vim9script()))
|
||||||
// number, possibly hidden
|
// number, possibly hidden
|
||||||
n = (long)tv_get_number(tv);
|
n = (long)tv_get_number(tv);
|
||||||
@ -1377,8 +1380,9 @@ ex_let_one(
|
|||||||
|
|
||||||
if (op != NULL && *op != '=')
|
if (op != NULL && *op != '=')
|
||||||
{
|
{
|
||||||
if ((opt_type == 1 && *op == '.')
|
if (((opt_type == gov_bool || opt_type == gov_number)
|
||||||
|| (opt_type == 0 && *op != '.'))
|
&& *op == '.')
|
||||||
|
|| (opt_type == gov_string && *op != '.'))
|
||||||
{
|
{
|
||||||
semsg(_(e_letwrong), op);
|
semsg(_(e_letwrong), op);
|
||||||
failed = TRUE; // don't set the value
|
failed = TRUE; // don't set the value
|
||||||
@ -1386,7 +1390,9 @@ ex_let_one(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (opt_type == 1) // number
|
// number, in legacy script also bool
|
||||||
|
if (opt_type == gov_number
|
||||||
|
|| (opt_type == gov_bool && !in_vim9script()))
|
||||||
{
|
{
|
||||||
switch (*op)
|
switch (*op)
|
||||||
{
|
{
|
||||||
@ -1397,7 +1403,8 @@ ex_let_one(
|
|||||||
case '%': n = (long)num_modulus(numval, n); break;
|
case '%': n = (long)num_modulus(numval, n); break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (opt_type == 0 && stringval != NULL && s != NULL)
|
else if (opt_type == gov_string
|
||||||
|
&& stringval != NULL && s != NULL)
|
||||||
{
|
{
|
||||||
// string
|
// string
|
||||||
s = concat_str(stringval, s);
|
s = concat_str(stringval, s);
|
||||||
@ -1409,7 +1416,7 @@ ex_let_one(
|
|||||||
|
|
||||||
if (!failed)
|
if (!failed)
|
||||||
{
|
{
|
||||||
if (opt_type != 0 || s != NULL)
|
if (opt_type != gov_string || s != NULL)
|
||||||
{
|
{
|
||||||
set_option_value(arg, n, s, opt_flags);
|
set_option_value(arg, n, s, opt_flags);
|
||||||
arg_end = p;
|
arg_end = p;
|
||||||
|
@ -1712,7 +1712,7 @@ get_option(void *data, int argc, Scheme_Object **argv)
|
|||||||
Vim_Prim *prim = (Vim_Prim *)data;
|
Vim_Prim *prim = (Vim_Prim *)data;
|
||||||
long value;
|
long value;
|
||||||
char *strval;
|
char *strval;
|
||||||
int rc;
|
getoption_T rc;
|
||||||
Scheme_Object *rval = NULL;
|
Scheme_Object *rval = NULL;
|
||||||
Scheme_Object *name = NULL;
|
Scheme_Object *name = NULL;
|
||||||
int opt_flags = 0;
|
int opt_flags = 0;
|
||||||
@ -1754,27 +1754,30 @@ get_option(void *data, int argc, Scheme_Object **argv)
|
|||||||
scheme_wrong_type(prim->name, "vim-buffer/window", 1, argc, argv);
|
scheme_wrong_type(prim->name, "vim-buffer/window", 1, argc, argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = get_option_value(BYTE_STRING_VALUE(name), &value, (char_u **)&strval, opt_flags);
|
rc = get_option_value(BYTE_STRING_VALUE(name), &value, (char_u **)&strval,
|
||||||
|
opt_flags);
|
||||||
curbuf = save_curb;
|
curbuf = save_curb;
|
||||||
curwin = save_curw;
|
curwin = save_curw;
|
||||||
|
|
||||||
switch (rc)
|
switch (rc)
|
||||||
{
|
{
|
||||||
case 1:
|
case gov_bool:
|
||||||
|
case gov_number:
|
||||||
MZ_GC_UNREG();
|
MZ_GC_UNREG();
|
||||||
return scheme_make_integer_value(value);
|
return scheme_make_integer_value(value);
|
||||||
case 0:
|
case gov_string:
|
||||||
rval = scheme_make_byte_string(strval);
|
rval = scheme_make_byte_string(strval);
|
||||||
MZ_GC_CHECK();
|
MZ_GC_CHECK();
|
||||||
vim_free(strval);
|
vim_free(strval);
|
||||||
MZ_GC_UNREG();
|
MZ_GC_UNREG();
|
||||||
return rval;
|
return rval;
|
||||||
case -1:
|
case gov_hidden_bool:
|
||||||
case -2:
|
case gov_hidden_number:
|
||||||
|
case gov_hidden_string:
|
||||||
MZ_GC_UNREG();
|
MZ_GC_UNREG();
|
||||||
raise_vim_exn(_("hidden option"));
|
raise_vim_exn(_("hidden option"));
|
||||||
//NOTREACHED
|
//NOTREACHED
|
||||||
case -3:
|
case gov_unknown:
|
||||||
MZ_GC_UNREG();
|
MZ_GC_UNREG();
|
||||||
raise_vim_exn(_("unknown option"));
|
raise_vim_exn(_("unknown option"));
|
||||||
//NOTREACHED
|
//NOTREACHED
|
||||||
|
@ -865,13 +865,11 @@ ex_ruby(exarg_T *eap)
|
|||||||
vim_str2rb_enc_str(const char *s)
|
vim_str2rb_enc_str(const char *s)
|
||||||
{
|
{
|
||||||
#if RUBY_VERSION >= 19
|
#if RUBY_VERSION >= 19
|
||||||
int isnum;
|
|
||||||
long lval;
|
long lval;
|
||||||
char_u *sval;
|
char_u *sval;
|
||||||
rb_encoding *enc;
|
rb_encoding *enc;
|
||||||
|
|
||||||
isnum = get_option_value((char_u *)"enc", &lval, &sval, 0);
|
if (get_option_value((char_u *)"enc", &lval, &sval, 0) == gov_string)
|
||||||
if (isnum == 0)
|
|
||||||
{
|
{
|
||||||
enc = rb_enc_find((char *)sval);
|
enc = rb_enc_find((char *)sval);
|
||||||
vim_free(sval);
|
vim_free(sval);
|
||||||
@ -886,14 +884,12 @@ vim_str2rb_enc_str(const char *s)
|
|||||||
eval_enc_string_protect(const char *str, int *state)
|
eval_enc_string_protect(const char *str, int *state)
|
||||||
{
|
{
|
||||||
#if RUBY_VERSION >= 19
|
#if RUBY_VERSION >= 19
|
||||||
int isnum;
|
|
||||||
long lval;
|
long lval;
|
||||||
char_u *sval;
|
char_u *sval;
|
||||||
rb_encoding *enc;
|
rb_encoding *enc;
|
||||||
VALUE v;
|
VALUE v;
|
||||||
|
|
||||||
isnum = get_option_value((char_u *)"enc", &lval, &sval, 0);
|
if (get_option_value((char_u *)"enc", &lval, &sval, 0) == gov_string)
|
||||||
if (isnum == 0)
|
|
||||||
{
|
{
|
||||||
enc = rb_enc_find((char *)sval);
|
enc = rb_enc_find((char *)sval);
|
||||||
vim_free(sval);
|
vim_free(sval);
|
||||||
|
30
src/option.c
30
src/option.c
@ -3834,13 +3834,15 @@ findoption(char_u *arg)
|
|||||||
* Get the value for an option.
|
* Get the value for an option.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
* Number or Toggle option: 1, *numval gets value.
|
* Number option: gov_number, *numval gets value.
|
||||||
* String option: 0, *stringval gets allocated string.
|
* Tottle option: gov_bool, *numval gets value.
|
||||||
* Hidden Number or Toggle option: -1.
|
* String option: gov_string, *stringval gets allocated string.
|
||||||
* hidden String option: -2.
|
* Hidden Number option: gov_hidden_number.
|
||||||
* unknown option: -3.
|
* Hidden Toggle option: gov_hidden_bool.
|
||||||
|
* Hidden String option: gov_hidden_string.
|
||||||
|
* Unknown option: gov_unknown.
|
||||||
*/
|
*/
|
||||||
int
|
getoption_T
|
||||||
get_option_value(
|
get_option_value(
|
||||||
char_u *name,
|
char_u *name,
|
||||||
long *numval,
|
long *numval,
|
||||||
@ -3851,7 +3853,7 @@ get_option_value(
|
|||||||
char_u *varp;
|
char_u *varp;
|
||||||
|
|
||||||
opt_idx = findoption(name);
|
opt_idx = findoption(name);
|
||||||
if (opt_idx < 0) // unknown option
|
if (opt_idx < 0) // option not in the table
|
||||||
{
|
{
|
||||||
int key;
|
int key;
|
||||||
|
|
||||||
@ -3861,6 +3863,7 @@ get_option_value(
|
|||||||
char_u key_name[2];
|
char_u key_name[2];
|
||||||
char_u *p;
|
char_u *p;
|
||||||
|
|
||||||
|
// check for a terminal option
|
||||||
if (key < 0)
|
if (key < 0)
|
||||||
{
|
{
|
||||||
key_name[0] = KEY2TERMCAP0(key);
|
key_name[0] = KEY2TERMCAP0(key);
|
||||||
@ -3876,10 +3879,10 @@ get_option_value(
|
|||||||
{
|
{
|
||||||
if (stringval != NULL)
|
if (stringval != NULL)
|
||||||
*stringval = vim_strsave(p);
|
*stringval = vim_strsave(p);
|
||||||
return 0;
|
return gov_string;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -3;
|
return gov_unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
varp = get_varp_scope(&(options[opt_idx]), opt_flags);
|
varp = get_varp_scope(&(options[opt_idx]), opt_flags);
|
||||||
@ -3887,7 +3890,7 @@ get_option_value(
|
|||||||
if (options[opt_idx].flags & P_STRING)
|
if (options[opt_idx].flags & P_STRING)
|
||||||
{
|
{
|
||||||
if (varp == NULL) // hidden option
|
if (varp == NULL) // hidden option
|
||||||
return -2;
|
return gov_hidden_string;
|
||||||
if (stringval != NULL)
|
if (stringval != NULL)
|
||||||
{
|
{
|
||||||
#ifdef FEAT_CRYPT
|
#ifdef FEAT_CRYPT
|
||||||
@ -3899,11 +3902,12 @@ get_option_value(
|
|||||||
#endif
|
#endif
|
||||||
*stringval = vim_strsave(*(char_u **)(varp));
|
*stringval = vim_strsave(*(char_u **)(varp));
|
||||||
}
|
}
|
||||||
return 0;
|
return gov_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (varp == NULL) // hidden option
|
if (varp == NULL) // hidden option
|
||||||
return -1;
|
return (options[opt_idx].flags & P_NUM)
|
||||||
|
? gov_hidden_number : gov_hidden_bool;
|
||||||
if (options[opt_idx].flags & P_NUM)
|
if (options[opt_idx].flags & P_NUM)
|
||||||
*numval = *(long *)varp;
|
*numval = *(long *)varp;
|
||||||
else
|
else
|
||||||
@ -3915,7 +3919,7 @@ get_option_value(
|
|||||||
else
|
else
|
||||||
*numval = (long) *(int *)varp;
|
*numval = (long) *(int *)varp;
|
||||||
}
|
}
|
||||||
return 1;
|
return (options[opt_idx].flags & P_NUM) ? gov_number : gov_bool;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
11
src/option.h
11
src/option.h
@ -60,6 +60,17 @@
|
|||||||
#define P_RWINONLY 0x10000000L // only redraw current window
|
#define P_RWINONLY 0x10000000L // only redraw current window
|
||||||
#define P_MLE 0x20000000L // under control of 'modelineexpr'
|
#define P_MLE 0x20000000L // under control of 'modelineexpr'
|
||||||
|
|
||||||
|
// Returned by get_option_value().
|
||||||
|
typedef enum {
|
||||||
|
gov_unknown,
|
||||||
|
gov_bool,
|
||||||
|
gov_number,
|
||||||
|
gov_string,
|
||||||
|
gov_hidden_bool,
|
||||||
|
gov_hidden_number,
|
||||||
|
gov_hidden_string
|
||||||
|
} getoption_T;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Default values for 'errorformat'.
|
* Default values for 'errorformat'.
|
||||||
* The "%f|%l| %m" one is used for when the contents of the quickfix window is
|
* The "%f|%l| %m" one is used for when the contents of the quickfix window is
|
||||||
|
@ -24,7 +24,7 @@ void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx);
|
|||||||
void set_term_option_sctx_idx(char *name, int opt_idx);
|
void set_term_option_sctx_idx(char *name, int opt_idx);
|
||||||
void check_redraw(long_u flags);
|
void check_redraw(long_u flags);
|
||||||
int findoption(char_u *arg);
|
int findoption(char_u *arg);
|
||||||
int get_option_value(char_u *name, long *numval, char_u **stringval, int opt_flags);
|
getoption_T get_option_value(char_u *name, long *numval, char_u **stringval, int opt_flags);
|
||||||
int get_option_value_strict(char_u *name, long *numval, char_u **stringval, int opt_type, void *from);
|
int get_option_value_strict(char_u *name, long *numval, char_u **stringval, int opt_type, void *from);
|
||||||
char_u *option_iter_next(void **option, int opt_type);
|
char_u *option_iter_next(void **option, int opt_type);
|
||||||
long_u get_option_flags(int opt_idx);
|
long_u get_option_flags(int opt_idx);
|
||||||
|
@ -3813,7 +3813,7 @@ ex_spelldump(exarg_T *eap)
|
|||||||
|
|
||||||
if (no_spell_checking(curwin))
|
if (no_spell_checking(curwin))
|
||||||
return;
|
return;
|
||||||
get_option_value((char_u*)"spl", &dummy, &spl, OPT_LOCAL);
|
(void)get_option_value((char_u*)"spl", &dummy, &spl, OPT_LOCAL);
|
||||||
|
|
||||||
// Create a new empty buffer in a new window.
|
// Create a new empty buffer in a new window.
|
||||||
do_cmdline_cmd((char_u *)"new");
|
do_cmdline_cmd((char_u *)"new");
|
||||||
|
@ -45,6 +45,9 @@ def Test_assignment_bool()
|
|||||||
assert_equal(true, flag)
|
assert_equal(true, flag)
|
||||||
flag = 1 && false
|
flag = 1 && false
|
||||||
assert_equal(false, flag)
|
assert_equal(false, flag)
|
||||||
|
|
||||||
|
var cp: bool = &cp
|
||||||
|
var fen: bool = &l:fen
|
||||||
END
|
END
|
||||||
CheckScriptSuccess(lines)
|
CheckScriptSuccess(lines)
|
||||||
CheckDefAndScriptFailure(['var x: bool = 2'], 'E1012:')
|
CheckDefAndScriptFailure(['var x: bool = 2'], 'E1012:')
|
||||||
@ -118,6 +121,8 @@ def Test_assignment()
|
|||||||
assert_equal('new', s:newVar)
|
assert_equal('new', s:newVar)
|
||||||
|
|
||||||
set ts=7
|
set ts=7
|
||||||
|
var ts: number = &ts
|
||||||
|
assert_equal(7, ts)
|
||||||
&ts += 1
|
&ts += 1
|
||||||
assert_equal(8, &ts)
|
assert_equal(8, &ts)
|
||||||
&ts -= 3
|
&ts -= 3
|
||||||
|
@ -590,7 +590,7 @@ def Test_command_modifier_other()
|
|||||||
unlet g:readFile
|
unlet g:readFile
|
||||||
|
|
||||||
noswapfile edit XnoSwap
|
noswapfile edit XnoSwap
|
||||||
assert_equal(0, &l:swapfile)
|
assert_equal(false, &l:swapfile)
|
||||||
bwipe!
|
bwipe!
|
||||||
|
|
||||||
var caught = false
|
var caught = false
|
||||||
|
25
src/typval.c
25
src/typval.c
@ -1083,7 +1083,7 @@ eval_option(
|
|||||||
char_u *option_end;
|
char_u *option_end;
|
||||||
long numval;
|
long numval;
|
||||||
char_u *stringval;
|
char_u *stringval;
|
||||||
int opt_type;
|
getoption_T opt_type;
|
||||||
int c;
|
int c;
|
||||||
int working = (**arg == '+'); // has("+option")
|
int working = (**arg == '+'); // has("+option")
|
||||||
int ret = OK;
|
int ret = OK;
|
||||||
@ -1109,7 +1109,7 @@ eval_option(
|
|||||||
opt_type = get_option_value(*arg, &numval,
|
opt_type = get_option_value(*arg, &numval,
|
||||||
rettv == NULL ? NULL : &stringval, opt_flags);
|
rettv == NULL ? NULL : &stringval, opt_flags);
|
||||||
|
|
||||||
if (opt_type == -3) // invalid name
|
if (opt_type == gov_unknown)
|
||||||
{
|
{
|
||||||
if (rettv != NULL)
|
if (rettv != NULL)
|
||||||
semsg(_(e_unknown_option), *arg);
|
semsg(_(e_unknown_option), *arg);
|
||||||
@ -1117,28 +1117,39 @@ eval_option(
|
|||||||
}
|
}
|
||||||
else if (rettv != NULL)
|
else if (rettv != NULL)
|
||||||
{
|
{
|
||||||
if (opt_type == -2) // hidden string option
|
if (opt_type == gov_hidden_string)
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_STRING;
|
rettv->v_type = VAR_STRING;
|
||||||
rettv->vval.v_string = NULL;
|
rettv->vval.v_string = NULL;
|
||||||
}
|
}
|
||||||
else if (opt_type == -1) // hidden number option
|
else if (opt_type == gov_hidden_bool || opt_type == gov_hidden_number)
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_NUMBER;
|
rettv->v_type = in_vim9script() && opt_type == gov_hidden_bool
|
||||||
|
? VAR_BOOL : VAR_NUMBER;
|
||||||
rettv->vval.v_number = 0;
|
rettv->vval.v_number = 0;
|
||||||
}
|
}
|
||||||
else if (opt_type == 1) // number option
|
else if (opt_type == gov_bool || opt_type == gov_number)
|
||||||
|
{
|
||||||
|
if (in_vim9script() && opt_type == gov_bool)
|
||||||
|
{
|
||||||
|
rettv->v_type = VAR_BOOL;
|
||||||
|
rettv->vval.v_number = numval ? VVAL_TRUE : VVAL_FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_NUMBER;
|
rettv->v_type = VAR_NUMBER;
|
||||||
rettv->vval.v_number = numval;
|
rettv->vval.v_number = numval;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else // string option
|
else // string option
|
||||||
{
|
{
|
||||||
rettv->v_type = VAR_STRING;
|
rettv->v_type = VAR_STRING;
|
||||||
rettv->vval.v_string = stringval;
|
rettv->vval.v_string = stringval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (working && (opt_type == -2 || opt_type == -1))
|
else if (working && (opt_type == gov_hidden_bool
|
||||||
|
|| opt_type == gov_hidden_number
|
||||||
|
|| opt_type == gov_hidden_string))
|
||||||
ret = FAIL;
|
ret = FAIL;
|
||||||
|
|
||||||
*option_end = c; // put back for error messages
|
*option_end = c; // put back for error messages
|
||||||
|
@ -750,6 +750,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
2254,
|
||||||
/**/
|
/**/
|
||||||
2253,
|
2253,
|
||||||
/**/
|
/**/
|
||||||
|
@ -5193,7 +5193,7 @@ get_var_dest(
|
|||||||
{
|
{
|
||||||
int cc;
|
int cc;
|
||||||
long numval;
|
long numval;
|
||||||
int opt_type;
|
getoption_T opt_type;
|
||||||
|
|
||||||
*dest = dest_option;
|
*dest = dest_option;
|
||||||
if (cmdidx == CMD_final || cmdidx == CMD_const)
|
if (cmdidx == CMD_final || cmdidx == CMD_const)
|
||||||
@ -5214,15 +5214,24 @@ get_var_dest(
|
|||||||
opt_type = get_option_value(skip_option_env_lead(name),
|
opt_type = get_option_value(skip_option_env_lead(name),
|
||||||
&numval, NULL, *opt_flags);
|
&numval, NULL, *opt_flags);
|
||||||
*p = cc;
|
*p = cc;
|
||||||
if (opt_type == -3)
|
switch (opt_type)
|
||||||
{
|
{
|
||||||
|
case gov_unknown:
|
||||||
semsg(_(e_unknown_option), name);
|
semsg(_(e_unknown_option), name);
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
case gov_string:
|
||||||
if (opt_type == -2 || opt_type == 0)
|
case gov_hidden_string:
|
||||||
*type = &t_string;
|
*type = &t_string;
|
||||||
else
|
break;
|
||||||
*type = &t_number; // both number and boolean option
|
case gov_bool:
|
||||||
|
case gov_hidden_bool:
|
||||||
|
*type = &t_bool;
|
||||||
|
break;
|
||||||
|
case gov_number:
|
||||||
|
case gov_hidden_number:
|
||||||
|
*type = &t_number;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (*name == '$')
|
else if (*name == '$')
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user