0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

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.
This commit is contained in:
Bram Moolenaar 2019-07-13 22:46:10 +02:00
parent 809ce4d317
commit d5abb4c877
15 changed files with 396 additions and 344 deletions

View File

@ -58,7 +58,9 @@ List An ordered sequence of items, see |List| for details.
Dictionary An associative, unordered array: Each entry has a key and a
value. |Dictionary|
Example: {'blue': "#0000ff", 'red': "#ff0000"}
Examples:
{'blue': "#0000ff", 'red': "#ff0000"}
*{blue: "#0000ff", red: "#ff0000"}
Funcref A reference to a function |Funcref|.
Example: function("strlen")
@ -477,8 +479,14 @@ only appear once. Examples: >
A key is always a String. You can use a Number, it will be converted to a
String automatically. Thus the String '4' and the number 4 will find the same
entry. Note that the String '04' and the Number 04 are different, since the
Number will be converted to the String '4'. The empty string can be used as a
key.
Number will be converted to the String '4'. The empty string can also be used
as a key.
*literal-Dict*
To avoid having to put quotes around every key the *{} form can be used. This
does require the key to consist only of ASCII letters, digits, '-' and '_'.
Example: >
let mydict = *{zero: 0, one_key: 1, two-key: 2, 333: 3}
Note that 333 here is the string "333". Empty keys are not possible here.
A value can be any expression. Using a Dictionary for a value creates a
nested Dictionary: >

View File

@ -708,12 +708,34 @@ dict2string(typval_T *tv, int copyID, int restore_copyID)
return (char_u *)ga.ga_data;
}
/*
* 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)
{
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}.
*/
int
dict_get_tv(char_u **arg, typval_T *rettv, int evaluate)
dict_get_tv(char_u **arg, typval_T *rettv, int evaluate, int literal)
{
dict_T *d = NULL;
typval_T tvkey;
@ -750,8 +772,11 @@ 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 != ':')
{
semsg(_("E720: Missing colon in Dictionary: %s"), *arg);

View File

@ -4391,7 +4391,8 @@ eval6(
* $VAR environment variable
* (expression) nested expression
* [expr, expr] List
* {key: val, key: val} Dictionary
* {key: val, key: val} Dictionary
* *{key: val, key: val} Dictionary with literal keys
*
* Also handle:
* ! in front logical NOT
@ -4575,13 +4576,25 @@ 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;
/*

View File

@ -28,7 +28,7 @@ char_u *dict_get_string(dict_T *d, char_u *key, int save);
varnumber_T dict_get_number(dict_T *d, char_u *key);
varnumber_T dict_get_number_check(dict_T *d, char_u *key);
char_u *dict2string(typval_T *tv, int copyID, int restore_copyID);
int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate);
int dict_get_tv(char_u **arg, typval_T *rettv, int evaluate, int literal);
void dict_extend(dict_T *d1, dict_T *d2, char_u *action);
dictitem_T *dict_lookup(hashitem_T *hi);
int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive);

View File

@ -6,5 +6,5 @@
|~| @73
|~| @52|o+0#0000001#ffd7ff255|t|h|e|r| |t|a|b| @11
|~+0#4040ff13#ffffff0| @52|a+0#0000001#ffd7ff255| |c+0#ff404010&|o|m@1|e|n|t| +0#0000001&|l|i|n|e| @6
|:+0#0000000#ffffff0|c|a|l@1| |p|o|p|u|p|_|m|o|v|e|(|p|o|p|u|p|w|i|n|,| |{|'|l|i|n|e|'|:| |7|,| |'|c|o|l|'|:| |5@1|}|)| @3|t+0#0000001#ffd7ff255|h|i|s| |l|i|n|e| |w|i|l@1| |n|o|t| |f|i
|:+0#0000000#ffffff0|c|a|l@1| |p|o|p|u|p|_|m|o|v|e|(|p|o|p|u|p|w|i|n|,| |*|{|l|i|n|e|:| |7|,| |c|o|l|:| |5@1|}|)| @6|t+0#0000001#ffd7ff255|h|i|s| |l|i|n|e| |w|i|l@1| |n|o|t| |f|i
| +0#0000000#ffffff0@53|t+0#0000001#ffd7ff255| |h|e|r|e| @14

View File

@ -10,4 +10,4 @@
|1|2|3|4|5|6|7|8|9|1|0|║+0#0000001#ffd7ff255| @10|1+0#0000000#ffffff0|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2
|1|2|3|4|5|6|7|8|9|1|0|╚+0#0000001#ffd7ff255|═|1+0#0000000#ffffff0|2|1|═+0#0000001#ffd7ff255@4|1+0#0000000#ffffff0|6|1|7|═+0#0000001#ffd7ff255@1|╝|9+0#0000000#ffffff0|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2
|1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2
|:|c|a|l@1| |p|o|p|u|p|_|m|o|v|e|(|w|i|n|i|d|b|,| |{|'|c|o|l|'|:| |1|2|}|)| @19|1|,|1| @10|T|o|p|
|:|c|a|l@1| |p|o|p|u|p|_|m|o|v|e|(|w|i|n|i|d|b|,| |*|{|c|o|l|:| |1|2|}|)| @20|1|,|1| @10|T|o|p|

View File

@ -10,4 +10,4 @@
|1+0#0000000#ffffff0|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|║+0#0000001#ffd7ff255| @10|2+0#0000000#ffffff0
|1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|╚+0#0000001#ffd7ff255|═|7+0#0000000#ffffff0|3|8|═+0#0000001#ffd7ff255@4|1+0#0000000#ffffff0|4|2
|1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2
|:|c|a|l@1| |p|o|p|u|p|_|m|o|v|e|(|w|i|n|i|d|b|,| |{|'|c|o|l|'|:| |6|3|}|)| @19|1|,|1| @10|T|o|p|
|:|c|a|l@1| |p|o|p|u|p|_|m|o|v|e|(|w|i|n|i|d|b|,| |*|{|c|o|l|:| |6|3|}|)| @20|1|,|1| @10|T|o|p|

View File

@ -10,4 +10,4 @@
| +0#0000001#ffd7ff255@6|8+0#0000000#ffffff0|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2
|═+0#0000001#ffd7ff255@4|6+0#0000000#ffffff0|7|8|9|═+0#0000001#ffd7ff255@1|╝|1+0#0000000#ffffff0@1|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2
|1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2
|:|c|a|l@1| |p|o|p|u|p|_|m|o|v|e|(|w|i|n|i|d|b|,| |{|'|p|o|s|'|:| |'|t|o|p|r|i|g|h|t|'|,| |'|c|o|l|'|:| |1|2|}|)| |1|,|1| @10|T|o|p|
|:|c|a|l@1| |p|o|p|u|p|_|m|o|v|e|(|w|i|n|i|d|b|,| |*|{|p|o|s|:| |'|t|o|p|r|i|g|h|t|'|,| |c|o|l|:| |1|2|}|)| @3|1|,|1| @10|T|o|p|

View File

@ -10,4 +10,4 @@
|1|2|3|4|5|6|7|8|9|1|0|1@2|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|2|7|2|8|2|9|3|0|3|1|3|2|3@2|4|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2
| +0&#e0e0e08@11|1+0&#ffffff0@1|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|2|6|═+0#0000001#ffd7ff255@13|X|4+0#0000000#ffffff0|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2
|o+0&#e0e0e08|m|e| |5+0&#ffffff0|6|7|t+0&#e0e0e08| @3|1+0&#ffffff0@1|2|1|3|1|4|1|5|1|6|1|7|1|8|1|9|2|0|2|1|2@2|3|2|4|2|5|║+0#0000001#ffd7ff255| @4|2+0#0000000#ffffff0|9|3| +0#0000001#ffd7ff255@6|║|4+0#0000000#ffffff0|3|5|3|6|3|7|3|8|3|9|4|0|4|1|4|2
|:|c|t+0&#e0e0e08|h|l+0&#ffffff0| |p|l+0&#e0e0e08|i|n|e| |m+0&#ffffff0|o|v|e|(|w|i|n|i|d|b|,| |{|'|p|o|s|'|:| |'|t|o|p|l|e|f|t|║+0#0000001#ffd7ff255| |j|u|s|t|l+0#0000000#ffffff0|'|:|e+0#0000001#ffd7ff255| |l|i|n|e| |║|,+0#0000000#ffffff0|1| @10|T|o|p|
|:|c|t+0&#e0e0e08|h|l+0&#ffffff0| |p|l+0&#e0e0e08|i|n|e| |m+0&#ffffff0|o|v|e|(|w|i|n|i|d|b|,| |*|{|p|o|s|:| |'|t|o|p|l|e|f|t|'|║+0#0000001#ffd7ff255| |j|u|s|t| +0#0000000#ffffff0|4|2|e+0#0000001#ffd7ff255| |l|i|n|e| |║|,+0#0000000#ffffff0|1| @10|T|o|p|

View File

@ -7,4 +7,4 @@
|7| @31|f+0#0000001#ffd7ff255|i|v|e| @3| +0#0000000#a8a8a8255| +0&#ffffff0@32
|8| @73
|9| @73
|:|c|a|l@1| |p|o|p|u|p|_|s|e|t|o|p|t|i|o|n|s|(|w|i|n|i|d|,| |{|'|f|i|r|s|t|l|i|n|e|'|:| |2|}|)| @9|1|,|1| @10|T|o|p|
|:|c|a|l@1| |p|o|p|u|p|_|s|e|t|o|p|t|i|o|n|s|(|w|i|n|i|d|,| |*|{|f|i|r|s|t|l|i|n|e|:| |2|}|)| @10|1|,|1| @10|T|o|p|

View File

@ -7,4 +7,4 @@
|7| @31|n+0#0000001#ffd7ff255|i|n|e| @3| +0#0000000#0000001| +0&#ffffff0@32
|8| @73
|9| @73
|:|c|a|l@1| |p|o|p|u|p|_|s|e|t|o|p|t|i|o|n|s|(|w|i|n|i|d|,| |{|'|f|i|r|s|t|l|i|n|e|'|:| |6|}|)| @9|1|,|1| @10|T|o|p|
|:|c|a|l@1| |p|o|p|u|p|_|s|e|t|o|p|t|i|o|n|s|(|w|i|n|i|d|,| |*|{|f|i|r|s|t|l|i|n|e|:| |6|}|)| @10|1|,|1| @10|T|o|p|

View File

@ -7,4 +7,4 @@
|7| @73
|8| @73
|9| @73
|:|c|a|l@1| |p|o|p|u|p|_|s|e|t|o|p|t|i|o|n|s|(|w|i|n|i|d|,| |{|'|f|i|r|s|t|l|i|n|e|'|:| |9|}|)| @9|1|,|1| @10|T|o|p|
|:|c|a|l@1| |p|o|p|u|p|_|s|e|t|o|p|t|i|o|n|s|(|w|i|n|i|d|,| |*|{|f|i|r|s|t|l|i|n|e|:| |9|}|)| @10|1|,|1| @10|T|o|p|

View File

@ -280,6 +280,10 @@ func Test_dict_func_remove_in_use()
call assert_equal(expected, d.func(string(remove(d, 'func'))))
endfunc
func Test_dict_literal_keys()
call assert_equal({'one': 1, 'two2': 2, '3three': 3, '44': 4}, *{one: 1, two2: 2, 3three: 3, 44: 4},)
endfunc
" Nasty: deepcopy() dict that refers to itself (fails when noref used)
func Test_dict_deepcopy()
let d = {1:1, 2:2}

File diff suppressed because it is too large Load Diff

View File

@ -777,6 +777,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1683,
/**/
1682,
/**/