forked from aniani/vim
patch 8.2.2753: Vim9: cannot ignore an item in assignment unpack
Problem: Vim9: cannot ignore an item in assignment unpack. Solution: Allow using an underscore.
This commit is contained in:
@@ -335,6 +335,18 @@ The "g:" prefix is not needed for auto-load functions.
|
||||
Since `&opt = value` is now assigning a value to option "opt", ":&" cannot be
|
||||
used to repeat a `:substitute` command.
|
||||
|
||||
For an unpack assignment the underscore can be used to ignore a list item,
|
||||
similar to how a function argument can be ignored: >
|
||||
[a, _, c] = theList
|
||||
[a, b; _] = longList
|
||||
|
||||
< *E1092*
|
||||
Declaring more than one variable at a time, using the unpack notation, is
|
||||
currently not supported: >
|
||||
var [v1, v2] = GetValues() # Error!
|
||||
That is because the type needs to be inferred from the list item type, which
|
||||
isn't that easy.
|
||||
|
||||
|
||||
Constants ~
|
||||
*vim9-const* *vim9-final*
|
||||
@@ -368,13 +380,6 @@ The constant only applies to the value itself, not what it refers to. >
|
||||
NAMES[1] = ["Emma"] # Error!
|
||||
NAMES[1][0] = "Emma" # OK, now females[0] == "Emma"
|
||||
|
||||
< *E1092*
|
||||
Declaring more than one variable at a time, using the unpack notation, is
|
||||
currently not supported: >
|
||||
var [v1, v2] = GetValues() # Error!
|
||||
That is because the type needs to be inferred from the list item type, which
|
||||
isn't that easy.
|
||||
|
||||
|
||||
Omitting :call and :eval ~
|
||||
|
||||
|
@@ -3514,7 +3514,7 @@ eval7(
|
||||
{
|
||||
int flags = evalarg == NULL ? 0 : evalarg->eval_flags;
|
||||
|
||||
if (in_vim9script() && len == 1 && *s == '_')
|
||||
if (evaluate && in_vim9script() && len == 1 && *s == '_')
|
||||
{
|
||||
emsg(_(e_cannot_use_underscore_here));
|
||||
ret = FAIL;
|
||||
|
@@ -970,8 +970,8 @@ ex_let_vars(
|
||||
{
|
||||
arg = skipwhite(arg + 1);
|
||||
++var_idx;
|
||||
arg = ex_let_one(arg, &item->li_tv, TRUE, flags, (char_u *)",;]",
|
||||
op, var_idx);
|
||||
arg = ex_let_one(arg, &item->li_tv, TRUE,
|
||||
flags | ASSIGN_UNPACK, (char_u *)",;]", op, var_idx);
|
||||
item = item->li_next;
|
||||
if (arg == NULL)
|
||||
return FAIL;
|
||||
@@ -996,8 +996,8 @@ ex_let_vars(
|
||||
l->lv_refcount = 1;
|
||||
++var_idx;
|
||||
|
||||
arg = ex_let_one(skipwhite(arg + 1), <v, FALSE, flags,
|
||||
(char_u *)"]", op, var_idx);
|
||||
arg = ex_let_one(skipwhite(arg + 1), <v, FALSE,
|
||||
flags | ASSIGN_UNPACK, (char_u *)"]", op, var_idx);
|
||||
clear_tv(<v);
|
||||
if (arg == NULL)
|
||||
return FAIL;
|
||||
@@ -3190,7 +3190,9 @@ set_var_const(
|
||||
var_in_vim9script = is_script_local && current_script_is_vim9();
|
||||
if (var_in_vim9script && name[0] == '_' && name[1] == NUL)
|
||||
{
|
||||
emsg(_(e_cannot_use_underscore_here));
|
||||
// For "[a, _] = list" the underscore is ignored.
|
||||
if ((flags & ASSIGN_UNPACK) == 0)
|
||||
emsg(_(e_cannot_use_underscore_here));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
|
@@ -256,6 +256,14 @@ def Test_assign_unpack()
|
||||
[v1, v2] = [1, 2]
|
||||
assert_equal(1, v1)
|
||||
assert_equal(2, v2)
|
||||
|
||||
[v1, _, v2, _] = [1, 99, 2, 77]
|
||||
assert_equal(1, v1)
|
||||
assert_equal(2, v2)
|
||||
|
||||
[v1, v2; _] = [1, 2, 3, 4, 5]
|
||||
assert_equal(1, v1)
|
||||
assert_equal(2, v2)
|
||||
END
|
||||
CheckDefAndScriptSuccess(lines)
|
||||
|
||||
|
@@ -750,6 +750,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
2753,
|
||||
/**/
|
||||
2752,
|
||||
/**/
|
||||
|
@@ -2152,10 +2152,11 @@ typedef enum {
|
||||
} estack_arg_T;
|
||||
|
||||
// Flags for assignment functions.
|
||||
#define ASSIGN_FINAL 1 // ":final"
|
||||
#define ASSIGN_CONST 2 // ":const"
|
||||
#define ASSIGN_NO_DECL 4 // "name = expr" without ":let"/":const"/":final"
|
||||
#define ASSIGN_DECL 8 // may declare variable if it does not exist
|
||||
#define ASSIGN_FINAL 0x01 // ":final"
|
||||
#define ASSIGN_CONST 0x02 // ":const"
|
||||
#define ASSIGN_NO_DECL 0x04 // "name = expr" without ":let"/":const"/":final"
|
||||
#define ASSIGN_DECL 0x08 // may declare variable if it does not exist
|
||||
#define ASSIGN_UNPACK 0x10 // using [a, b] = list
|
||||
|
||||
#include "ex_cmds.h" // Ex command defines
|
||||
#include "spell.h" // spell checking stuff
|
||||
|
@@ -6369,6 +6369,17 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
||||
{
|
||||
int instr_count = -1;
|
||||
|
||||
if (var_start[0] == '_' && !eval_isnamec(var_start[1]))
|
||||
{
|
||||
// Ignore underscore in "[a, _, b] = list".
|
||||
if (var_count > 0)
|
||||
{
|
||||
var_start = skipwhite(var_start + 2);
|
||||
continue;
|
||||
}
|
||||
emsg(_(e_cannot_use_underscore_here));
|
||||
goto theend;
|
||||
}
|
||||
vim_free(lhs.lhs_name);
|
||||
|
||||
/*
|
||||
@@ -6388,11 +6399,6 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
||||
semsg(_(e_cannot_assign_to_constant), lhs.lhs_name);
|
||||
goto theend;
|
||||
}
|
||||
if (is_decl && lhs.lhs_name[0] == '_' && lhs.lhs_name[1] == NUL)
|
||||
{
|
||||
emsg(_(e_cannot_use_underscore_here));
|
||||
goto theend;
|
||||
}
|
||||
|
||||
if (!heredoc)
|
||||
{
|
||||
|
Reference in New Issue
Block a user