diff options
author | erw7 <erw7.github@gmail.com> | 2019-05-29 12:06:39 +0900 |
---|---|---|
committer | erw7 <erw7.github@gmail.com> | 2019-05-29 12:54:42 +0900 |
commit | bfc44a91acdfb968cb3d0d21effc4ea9cbcd09e1 (patch) | |
tree | db93be271b130d3e328373ee9b895d2b711ea8ff | |
parent | d46aaa074640ef92382e5800297b7c76ed7574da (diff) | |
download | rneovim-bfc44a91acdfb968cb3d0d21effc4ea9cbcd09e1.tar.gz rneovim-bfc44a91acdfb968cb3d0d21effc4ea9cbcd09e1.tar.bz2 rneovim-bfc44a91acdfb968cb3d0d21effc4ea9cbcd09e1.zip |
vim-patch:8.1.1114: confusing overloaded operator "." for string concatenation
Problem: Confusing overloaded operator "." for string concatenation.
Solution: Add ".." for string concatenation. Also "let a ..= b".
https://github.com/vim/vim/commit/0f248b006c2574abc00c9aa7886d8f33620eb822
-rw-r--r-- | runtime/doc/eval.txt | 17 | ||||
-rw-r--r-- | src/nvim/eval.c | 12 | ||||
-rw-r--r-- | src/nvim/testdir/test_eval_stuff.vim | 29 |
3 files changed, 50 insertions, 8 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index f035c754c0..cc97117ffd 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -610,10 +610,10 @@ Expression syntax summary, from least to most significant: expr2 ? expr1 : expr1 if-then-else |expr2| expr3 - expr3 || expr3 .. logical OR + expr3 || expr3 ... logical OR |expr3| expr4 - expr4 && expr4 .. logical AND + expr4 && expr4 ... logical AND |expr4| expr5 expr5 == expr5 equal @@ -634,9 +634,10 @@ Expression syntax summary, from least to most significant: expr5 isnot expr5 different |List| instance |expr5| expr6 - expr6 + expr6 .. number addition or list concatenation - expr6 - expr6 .. number subtraction - expr6 . expr6 .. string concatenation + expr6 + expr6 .. number addition or list concatenation + expr6 - expr6 .. number subtraction + expr6 . expr6 .. string concatenation + expr6 .. expr6 .. string concatenation |expr6| expr7 expr7 * expr7 .. number multiplication @@ -670,7 +671,7 @@ Expression syntax summary, from least to most significant: {args -> expr1} lambda expression -".." indicates that the operations in this level can be concatenated. +"..." indicates that the operations in this level can be concatenated. Example: > &nu || &list && &shell == "csh" @@ -850,10 +851,14 @@ expr5 and expr6 *expr5* *expr6* expr6 + expr6 .. Number addition or |List| concatenation *expr-+* expr6 - expr6 .. Number subtraction *expr--* expr6 . expr6 .. String concatenation *expr-.* +expr6 .. expr6 .. String concatenation *expr-..* For |Lists| only "+" is possible and then both expr6 must be a list. The result is a new list with the two lists Concatenated. +For String concatenation ".." is preferred, since "." is ambiguous, it is also +used for |Dict| member access and floating point numbers. + expr7 * expr7 .. Number multiplication *expr-star* expr7 / expr7 .. Number division *expr-/* expr7 % expr7 .. Number modulo *expr-%* diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 7d7c2d3f33..1640729c94 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -1446,6 +1446,7 @@ int eval_foldexpr(char_u *arg, int *cp) * ":let var /= expr" assignment command. * ":let var %= expr" assignment command. * ":let var .= expr" assignment command. + * ":let var ..= expr" assignment command. * ":let [var1, var2] = expr" unpack list. */ void ex_let(exarg_T *eap) @@ -1468,8 +1469,8 @@ void ex_let(exarg_T *eap) argend--; } expr = skipwhite(argend); - if (*expr != '=' && !(vim_strchr((char_u *)"+-*/%.", *expr) != NULL - && expr[1] == '=')) { + if (*expr != '=' && !((vim_strchr((char_u *)"+-*/%.", *expr) != NULL + && expr[1] == '=') || STRNCMP(expr, "..=", 3) == 0)) { // ":let" without "=": list variables if (*arg == '[') { EMSG(_(e_invarg)); @@ -1493,6 +1494,9 @@ void ex_let(exarg_T *eap) if (*expr != '=') { if (vim_strchr((char_u *)"+-*/%.", *expr) != NULL) { op[0] = *expr; // +=, -=, *=, /=, %= or .= + if (expr[0] == '.' && expr[1] == '.') { // ..= + expr++; + } } expr = skipwhite(expr + 2); } else { @@ -3789,6 +3793,7 @@ static int eval4(char_u **arg, typval_T *rettv, int evaluate) * + number addition * - number subtraction * . string concatenation + * .. string concatenation * * "arg" must point to the first non-white of the expression. * "arg" is advanced to the next non-white after the recognized expression. @@ -3836,6 +3841,9 @@ static int eval5(char_u **arg, typval_T *rettv, int evaluate) /* * Get the second variable. */ + if (op == '.' && *(*arg + 1) == '.') { // ..string concatenation + (*arg)++; + } *arg = skipwhite(*arg + 1); if (eval6(arg, &var2, evaluate, op == '.') == FAIL) { tv_clear(rettv); diff --git a/src/nvim/testdir/test_eval_stuff.vim b/src/nvim/testdir/test_eval_stuff.vim index 1850fb0cf1..19a15590e5 100644 --- a/src/nvim/testdir/test_eval_stuff.vim +++ b/src/nvim/testdir/test_eval_stuff.vim @@ -49,3 +49,32 @@ func Test_line_continuation() "\ and some more call assert_equal([5, 6], array) endfunc + +func Test_string_concatenation() + call assert_equal('ab', 'a'.'b') + call assert_equal('ab', 'a' .'b') + call assert_equal('ab', 'a'. 'b') + call assert_equal('ab', 'a' . 'b') + + call assert_equal('ab', 'a'..'b') + call assert_equal('ab', 'a' ..'b') + call assert_equal('ab', 'a'.. 'b') + call assert_equal('ab', 'a' .. 'b') + + let a = 'a' + let b = 'b' + let a .= b + call assert_equal('ab', a) + + let a = 'a' + let a.=b + call assert_equal('ab', a) + + let a = 'a' + let a ..= b + call assert_equal('ab', a) + + let a = 'a' + let a..=b + call assert_equal('ab', a) +endfunc |