patch 9.2.1136: Vim9: cannot change an item of a read-only v: variable in :def
Problem: Assigning to an item of a read-only v: variable, gives E46 in
a :def function, while it works at the script level and
":help clipboard-providers-define" does it.
Solution: Check that a v: variable is read-only only when no index
follows, as for a script variable. Make v:clipproviders an
empty dict at startup, as v:colornames, so that a :def function
can add the first item.
closes: #21391
Assisted-by: Claude
Signed-off-by: Hirohito Higashi <h.east.727@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
1 parent
10b37abb11
commit
0104c2052a
6 files changed
+32
-3
No files matched your search
@@ -273,6 +273,7 @@ evalvars_init(void)
|
||||
set_vim_var_nr(VV_ECHOSPACE, sc_col - 1);
|
||||
|
||||
set_vim_var_dict(VV_COLORNAMES, dict_alloc());
|
||||
set_vim_var_dict(VV_CLIPPROVIDERS, dict_alloc());
|
||||
|
||||
#ifdef FEAT_PYTHON3
|
||||
set_vim_var_nr(VV_PYTHON3_VERSION, python3_version());
|
||||
|
||||
@@ -22,7 +22,7 @@ char_u *compile_one_expr_in_str(char_u *p, cctx_T *cctx);
|
||||
int compile_all_expr_in_str(char_u *str, int evalstr, cctx_T *cctx);
|
||||
int assignment_len(char_u *p, int *heredoc);
|
||||
void vim9_declare_error(char_u *name);
|
||||
int get_var_dest(char_u *name, assign_dest_T *dest, cmdidx_T cmdidx, int *option_scope, int *vimvaridx, type_T **type, cctx_T *cctx);
|
||||
int get_var_dest(char_u *name, assign_dest_T *dest, cmdidx_T cmdidx, int has_index, int *option_scope, int *vimvaridx, type_T **type, cctx_T *cctx);
|
||||
int compile_lhs(char_u *var_start, lhs_T *lhs, cmdidx_T cmdidx, int heredoc, int has_cmd, int oplen, cctx_T *cctx);
|
||||
int compile_assign_lhs(char_u *var_start, lhs_T *lhs, cmdidx_T cmdidx, int is_decl, int heredoc, int has_cmd, int oplen, cctx_T *cctx);
|
||||
int compile_load_lhs_with_index(lhs_T *lhs, char_u *var_start, cctx_T *cctx);
|
||||
|
||||
@@ -248,6 +248,28 @@ def Test_assignment()
|
||||
END
|
||||
enddef
|
||||
|
||||
" An item of a read-only v: variable can be changed in a :def function, as
|
||||
" at the script level, the variable itself cannot.
|
||||
def Test_assign_item_of_readonly_vim_var()
|
||||
assert_equal(v:t_dict, type(v:clipproviders))
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
def Define()
|
||||
v:clipproviders['vim9_one'] = {}
|
||||
v:clipproviders.vim9_two = {}
|
||||
enddef
|
||||
Define()
|
||||
assert_equal({}, v:clipproviders.vim9_one)
|
||||
assert_equal({}, v:clipproviders.vim9_two)
|
||||
remove(v:clipproviders, 'vim9_one')
|
||||
remove(v:clipproviders, 'vim9_two')
|
||||
END
|
||||
v9.CheckScriptSuccess(lines)
|
||||
|
||||
v9.CheckDefFailure(['v:clipproviders = {}'], 'E46:')
|
||||
v9.CheckDefFailure(['v:version[0] = 1'], 'E1141:')
|
||||
enddef
|
||||
|
||||
def Test_float_and_number()
|
||||
var lines =<< trim END
|
||||
var f: float
|
||||
|
||||
@@ -763,6 +763,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1136,
|
||||
/**/
|
||||
1135,
|
||||
/**/
|
||||
|
||||
+1
-1
@@ -1151,7 +1151,7 @@ compile_for(char_u *arg_start, cctx_T *cctx)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (get_var_dest(name, &dest, CMD_for, &opt_flags,
|
||||
if (get_var_dest(name, &dest, CMD_for, FALSE, &opt_flags,
|
||||
&vimvaridx, &type, cctx) == FAIL)
|
||||
goto failed;
|
||||
if (dest != dest_local)
|
||||
|
||||
+5
-1
@@ -1493,6 +1493,7 @@ valid_dest_reg(int name)
|
||||
* For an option "option_scope" is set.
|
||||
* For a v:var "vimvaridx" is set.
|
||||
* "type" is set to the destination type if known, unchanted otherwise.
|
||||
* When "has_index" is TRUE an item of the variable is assigned to.
|
||||
* Return FAIL if an error message was given.
|
||||
*/
|
||||
int
|
||||
@@ -1500,6 +1501,7 @@ get_var_dest(
|
||||
char_u *name,
|
||||
assign_dest_T *dest,
|
||||
cmdidx_T cmdidx,
|
||||
int has_index,
|
||||
int *option_scope,
|
||||
int *vimvaridx,
|
||||
type_T **type,
|
||||
@@ -1600,8 +1602,9 @@ get_var_dest(
|
||||
semsg(_(e_variable_not_found_str), name);
|
||||
return FAIL;
|
||||
}
|
||||
// An item of a read-only variable can be changed, as when not compiled.
|
||||
// We use the current value of "sandbox" here, is that OK?
|
||||
if (var_check_ro(di_flags, name, FALSE))
|
||||
if (!has_index && var_check_ro(di_flags, name, FALSE))
|
||||
return FAIL;
|
||||
*dest = dest_vimvar;
|
||||
vtv = get_vim_var_tv(*vimvaridx);
|
||||
@@ -1961,6 +1964,7 @@ compile_lhs_var_dest(
|
||||
int declare_error = FALSE;
|
||||
|
||||
if (get_var_dest(lhs->lhs_name, &lhs->lhs_dest, cmdidx,
|
||||
lhs->lhs_has_index,
|
||||
&lhs->lhs_opt_flags, &lhs->lhs_vimvaridx,
|
||||
&lhs->lhs_type, cctx) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
Reference in new issue
Block a user