vim-patch:8.1.1683: dictionary with string keys is longer than needed

Problem:    Dictionary with string keys is longer than needed.
Solution:   Use *{key: val} for literaly keys.
d5abb4c877

Vim's popup,textprop features are N/A.
Neovim has not polyfilled their APIs.
Skip docs and tests for these features.
This commit is contained in:
Jan Edmund Lazo
2020-10-07 00:03:12 -04:00
parent fa1e740e60
commit 7ca5dc2519
3 changed files with 56 additions and 11 deletions

View File

@@ -3905,6 +3905,7 @@ static int eval6(char_u **arg, typval_T *rettv, int evaluate, int want_string)
// (expression) nested expression
// [expr, expr] List
// {key: val, key: val} Dictionary
// *{key: val, key: val} Dictionary with literal keys
//
// Also handle:
// ! in front logical NOT
@@ -4012,11 +4013,21 @@ static int eval7(
case '[': ret = get_list_tv(arg, rettv, evaluate);
break;
// Dictionary: *{key: val, key: val}
case '*':
if ((*arg)[1] == '{') {
(*arg)++;
ret = dict_get_tv(arg, rettv, evaluate, true);
} else {
ret = NOTDONE;
}
break;
// Lambda: {arg, arg -> expr}
// Dictionary: {key: val, key: val}
// Dictionary: {'key': val, 'key': val}
case '{': ret = get_lambda_tv(arg, rettv, evaluate);
if (ret == NOTDONE) {
ret = dict_get_tv(arg, rettv, evaluate);
ret = dict_get_tv(arg, rettv, evaluate, false);
}
break;
@@ -5347,11 +5358,31 @@ static inline bool set_ref_dict(dict_T *dict, int copyID)
return false;
}
/*
* Allocate a variable for a Dictionary and fill it from "*arg".
* Return OK or FAIL. Returns NOTDONE for {expr}.
*/
static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate)
// Get the key for *{key: val} into "tv" and advance "arg".
// Return FAIL when there is no valid key.
static int get_literal_key(char_u **arg, typval_T *tv)
FUNC_ATTR_NONNULL_ALL
{
char_u *p;
if (!ASCII_ISALNUM(**arg) && **arg != '_' && **arg != '-') {
return FAIL;
}
for (p = *arg; ASCII_ISALNUM(*p) || *p == '_' || *p == '-'; p++) {
}
tv->v_type = VAR_STRING;
tv->vval.v_string = vim_strnsave(*arg, (int)(p - *arg));
*arg = skipwhite(p);
return OK;
}
// Allocate a variable for a Dictionary and fill it from "*arg".
// "literal" is true for *{key: val}
// Return OK or FAIL. Returns NOTDONE for {expr}.
static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate,
bool literal)
{
dict_T *d = NULL;
typval_T tvkey;
@@ -5385,7 +5416,9 @@ static int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate)
*arg = skipwhite(*arg + 1);
while (**arg != '}' && **arg != NUL) {
if (eval1(arg, &tvkey, evaluate) == FAIL) { // recursive!
if ((literal
? get_literal_key(arg, &tvkey)
: eval1(arg, &tvkey, evaluate)) == FAIL) { // recursive!
goto failret;
}
if (**arg != ':') {