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
|
||||
{
|
||||
long n = 0;
|
||||
int opt_type;
|
||||
getoption_T opt_type;
|
||||
long numval;
|
||||
char_u *stringval = NULL;
|
||||
char_u *s = NULL;
|
||||
@ -1364,7 +1364,10 @@ ex_let_one(
|
||||
*p = NUL;
|
||||
|
||||
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()))
|
||||
// number, possibly hidden
|
||||
n = (long)tv_get_number(tv);
|
||||
@ -1377,8 +1380,9 @@ ex_let_one(
|
||||
|
||||
if (op != NULL && *op != '=')
|
||||
{
|
||||
if ((opt_type == 1 && *op == '.')
|
||||
|| (opt_type == 0 && *op != '.'))
|
||||
if (((opt_type == gov_bool || opt_type == gov_number)
|
||||
&& *op == '.')
|
||||
|| (opt_type == gov_string && *op != '.'))
|
||||
{
|
||||
semsg(_(e_letwrong), op);
|
||||
failed = TRUE; // don't set the value
|
||||
@ -1386,7 +1390,9 @@ ex_let_one(
|
||||
}
|
||||
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)
|
||||
{
|
||||
@ -1397,7 +1403,8 @@ ex_let_one(
|
||||
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
|
||||
s = concat_str(stringval, s);
|
||||
@ -1409,7 +1416,7 @@ ex_let_one(
|
||||
|
||||
if (!failed)
|
||||
{
|
||||
if (opt_type != 0 || s != NULL)
|
||||
if (opt_type != gov_string || s != NULL)
|
||||
{
|
||||
set_option_value(arg, n, s, opt_flags);
|
||||
arg_end = p;
|
||||
|
@ -1712,7 +1712,7 @@ get_option(void *data, int argc, Scheme_Object **argv)
|
||||
Vim_Prim *prim = (Vim_Prim *)data;
|
||||
long value;
|
||||
char *strval;
|
||||
int rc;
|
||||
getoption_T rc;
|
||||
Scheme_Object *rval = NULL;
|
||||
Scheme_Object *name = NULL;
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
curwin = save_curw;
|
||||
|
||||
switch (rc)
|
||||
{
|
||||
case 1:
|
||||
case gov_bool:
|
||||
case gov_number:
|
||||
MZ_GC_UNREG();
|
||||
return scheme_make_integer_value(value);
|
||||
case 0:
|
||||
case gov_string:
|
||||
rval = scheme_make_byte_string(strval);
|
||||
MZ_GC_CHECK();
|
||||
vim_free(strval);
|
||||
MZ_GC_UNREG();
|
||||
return rval;
|
||||
case -1:
|
||||
case -2:
|
||||
case gov_hidden_bool:
|
||||
case gov_hidden_number:
|
||||
case gov_hidden_string:
|
||||
MZ_GC_UNREG();
|
||||
raise_vim_exn(_("hidden option"));
|
||||
//NOTREACHED
|
||||
case -3:
|
||||
case gov_unknown:
|
||||
MZ_GC_UNREG();
|
||||
raise_vim_exn(_("unknown option"));
|
||||
//NOTREACHED
|
||||
|
@ -865,13 +865,11 @@ ex_ruby(exarg_T *eap)
|
||||
vim_str2rb_enc_str(const char *s)
|
||||
{
|
||||
#if RUBY_VERSION >= 19
|
||||
int isnum;
|
||||
long lval;
|
||||
char_u *sval;
|
||||
rb_encoding *enc;
|
||||
|
||||
isnum = get_option_value((char_u *)"enc", &lval, &sval, 0);
|
||||
if (isnum == 0)
|
||||
if (get_option_value((char_u *)"enc", &lval, &sval, 0) == gov_string)
|
||||
{
|
||||
enc = rb_enc_find((char *)sval);
|
||||
vim_free(sval);
|
||||
@ -886,14 +884,12 @@ vim_str2rb_enc_str(const char *s)
|
||||
eval_enc_string_protect(const char *str, int *state)
|
||||
{
|
||||
#if RUBY_VERSION >= 19
|
||||
int isnum;
|
||||
long lval;
|
||||
char_u *sval;
|
||||
rb_encoding *enc;
|
||||
VALUE v;
|
||||
|
||||
isnum = get_option_value((char_u *)"enc", &lval, &sval, 0);
|
||||
if (isnum == 0)
|
||||
if (get_option_value((char_u *)"enc", &lval, &sval, 0) == gov_string)
|
||||
{
|
||||
enc = rb_enc_find((char *)sval);
|
||||
vim_free(sval);
|
||||
|
32
src/option.c
32
src/option.c
@ -3834,13 +3834,15 @@ findoption(char_u *arg)
|
||||
* Get the value for an option.
|
||||
*
|
||||
* Returns:
|
||||
* Number or Toggle option: 1, *numval gets value.
|
||||
* String option: 0, *stringval gets allocated string.
|
||||
* Hidden Number or Toggle option: -1.
|
||||
* hidden String option: -2.
|
||||
* unknown option: -3.
|
||||
* Number option: gov_number, *numval gets value.
|
||||
* Tottle option: gov_bool, *numval gets value.
|
||||
* String option: gov_string, *stringval gets allocated string.
|
||||
* Hidden Number option: gov_hidden_number.
|
||||
* Hidden Toggle option: gov_hidden_bool.
|
||||
* Hidden String option: gov_hidden_string.
|
||||
* Unknown option: gov_unknown.
|
||||
*/
|
||||
int
|
||||
getoption_T
|
||||
get_option_value(
|
||||
char_u *name,
|
||||
long *numval,
|
||||
@ -3851,16 +3853,17 @@ get_option_value(
|
||||
char_u *varp;
|
||||
|
||||
opt_idx = findoption(name);
|
||||
if (opt_idx < 0) // unknown option
|
||||
if (opt_idx < 0) // option not in the table
|
||||
{
|
||||
int key;
|
||||
|
||||
if (STRLEN(name) == 4 && name[0] == 't' && name[1] == '_'
|
||||
&& (key = find_key_option(name, FALSE)) != 0)
|
||||
&& (key = find_key_option(name, FALSE)) != 0)
|
||||
{
|
||||
char_u key_name[2];
|
||||
char_u *p;
|
||||
|
||||
// check for a terminal option
|
||||
if (key < 0)
|
||||
{
|
||||
key_name[0] = KEY2TERMCAP0(key);
|
||||
@ -3876,10 +3879,10 @@ get_option_value(
|
||||
{
|
||||
if (stringval != NULL)
|
||||
*stringval = vim_strsave(p);
|
||||
return 0;
|
||||
return gov_string;
|
||||
}
|
||||
}
|
||||
return -3;
|
||||
return gov_unknown;
|
||||
}
|
||||
|
||||
varp = get_varp_scope(&(options[opt_idx]), opt_flags);
|
||||
@ -3887,7 +3890,7 @@ get_option_value(
|
||||
if (options[opt_idx].flags & P_STRING)
|
||||
{
|
||||
if (varp == NULL) // hidden option
|
||||
return -2;
|
||||
return gov_hidden_string;
|
||||
if (stringval != NULL)
|
||||
{
|
||||
#ifdef FEAT_CRYPT
|
||||
@ -3899,11 +3902,12 @@ get_option_value(
|
||||
#endif
|
||||
*stringval = vim_strsave(*(char_u **)(varp));
|
||||
}
|
||||
return 0;
|
||||
return gov_string;
|
||||
}
|
||||
|
||||
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)
|
||||
*numval = *(long *)varp;
|
||||
else
|
||||
@ -3915,7 +3919,7 @@ get_option_value(
|
||||
else
|
||||
*numval = (long) *(int *)varp;
|
||||
}
|
||||
return 1;
|
||||
return (options[opt_idx].flags & P_NUM) ? gov_number : gov_bool;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
11
src/option.h
11
src/option.h
@ -60,6 +60,17 @@
|
||||
#define P_RWINONLY 0x10000000L // only redraw current window
|
||||
#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'.
|
||||
* 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 check_redraw(long_u flags);
|
||||
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);
|
||||
char_u *option_iter_next(void **option, int opt_type);
|
||||
long_u get_option_flags(int opt_idx);
|
||||
|
@ -3813,7 +3813,7 @@ ex_spelldump(exarg_T *eap)
|
||||
|
||||
if (no_spell_checking(curwin))
|
||||
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.
|
||||
do_cmdline_cmd((char_u *)"new");
|
||||
|
@ -45,6 +45,9 @@ def Test_assignment_bool()
|
||||
assert_equal(true, flag)
|
||||
flag = 1 && false
|
||||
assert_equal(false, flag)
|
||||
|
||||
var cp: bool = &cp
|
||||
var fen: bool = &l:fen
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
CheckDefAndScriptFailure(['var x: bool = 2'], 'E1012:')
|
||||
@ -118,6 +121,8 @@ def Test_assignment()
|
||||
assert_equal('new', s:newVar)
|
||||
|
||||
set ts=7
|
||||
var ts: number = &ts
|
||||
assert_equal(7, ts)
|
||||
&ts += 1
|
||||
assert_equal(8, &ts)
|
||||
&ts -= 3
|
||||
|
@ -590,7 +590,7 @@ def Test_command_modifier_other()
|
||||
unlet g:readFile
|
||||
|
||||
noswapfile edit XnoSwap
|
||||
assert_equal(0, &l:swapfile)
|
||||
assert_equal(false, &l:swapfile)
|
||||
bwipe!
|
||||
|
||||
var caught = false
|
||||
|
29
src/typval.c
29
src/typval.c
@ -1083,7 +1083,7 @@ eval_option(
|
||||
char_u *option_end;
|
||||
long numval;
|
||||
char_u *stringval;
|
||||
int opt_type;
|
||||
getoption_T opt_type;
|
||||
int c;
|
||||
int working = (**arg == '+'); // has("+option")
|
||||
int ret = OK;
|
||||
@ -1109,7 +1109,7 @@ eval_option(
|
||||
opt_type = get_option_value(*arg, &numval,
|
||||
rettv == NULL ? NULL : &stringval, opt_flags);
|
||||
|
||||
if (opt_type == -3) // invalid name
|
||||
if (opt_type == gov_unknown)
|
||||
{
|
||||
if (rettv != NULL)
|
||||
semsg(_(e_unknown_option), *arg);
|
||||
@ -1117,20 +1117,29 @@ eval_option(
|
||||
}
|
||||
else if (rettv != NULL)
|
||||
{
|
||||
if (opt_type == -2) // hidden string option
|
||||
if (opt_type == gov_hidden_string)
|
||||
{
|
||||
rettv->v_type = VAR_STRING;
|
||||
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;
|
||||
}
|
||||
else if (opt_type == 1) // number option
|
||||
else if (opt_type == gov_bool || opt_type == gov_number)
|
||||
{
|
||||
rettv->v_type = VAR_NUMBER;
|
||||
rettv->vval.v_number = numval;
|
||||
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->vval.v_number = numval;
|
||||
}
|
||||
}
|
||||
else // string option
|
||||
{
|
||||
@ -1138,7 +1147,9 @@ eval_option(
|
||||
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;
|
||||
|
||||
*option_end = c; // put back for error messages
|
||||
|
@ -750,6 +750,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
2254,
|
||||
/**/
|
||||
2253,
|
||||
/**/
|
||||
|
@ -5191,9 +5191,9 @@ get_var_dest(
|
||||
|
||||
if (*name == '&')
|
||||
{
|
||||
int cc;
|
||||
long numval;
|
||||
int opt_type;
|
||||
int cc;
|
||||
long numval;
|
||||
getoption_T opt_type;
|
||||
|
||||
*dest = dest_option;
|
||||
if (cmdidx == CMD_final || cmdidx == CMD_const)
|
||||
@ -5214,15 +5214,24 @@ get_var_dest(
|
||||
opt_type = get_option_value(skip_option_env_lead(name),
|
||||
&numval, NULL, *opt_flags);
|
||||
*p = cc;
|
||||
if (opt_type == -3)
|
||||
switch (opt_type)
|
||||
{
|
||||
semsg(_(e_unknown_option), name);
|
||||
return FAIL;
|
||||
case gov_unknown:
|
||||
semsg(_(e_unknown_option), name);
|
||||
return FAIL;
|
||||
case gov_string:
|
||||
case gov_hidden_string:
|
||||
*type = &t_string;
|
||||
break;
|
||||
case gov_bool:
|
||||
case gov_hidden_bool:
|
||||
*type = &t_bool;
|
||||
break;
|
||||
case gov_number:
|
||||
case gov_hidden_number:
|
||||
*type = &t_number;
|
||||
break;
|
||||
}
|
||||
if (opt_type == -2 || opt_type == 0)
|
||||
*type = &t_string;
|
||||
else
|
||||
*type = &t_number; // both number and boolean option
|
||||
}
|
||||
else if (*name == '$')
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user