diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-04-16 10:18:24 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-16 10:18:24 +0800 |
commit | e3c083832c77eb7c24442bd10bbb718599a764d9 (patch) | |
tree | 14fe2dfcfd05b95d57a01f2603f5d8760935fd52 | |
parent | b1e8b799a58f2b984b18940bb134996651aac248 (diff) | |
download | rneovim-e3c083832c77eb7c24442bd10bbb718599a764d9.tar.gz rneovim-e3c083832c77eb7c24442bd10bbb718599a764d9.tar.bz2 rneovim-e3c083832c77eb7c24442bd10bbb718599a764d9.zip |
vim-patch:9.1.0335: String interpolation fails for List type (#28364)
Problem: String interpolation fails for List type
Solution: use implicit string(list) for string interpolation and :put =
(Yegappan Lakshmanan)
related: vim/vim#14529
closes: vim/vim#14556
https://github.com/vim/vim/commit/bce51d9005dd1c5bc002acbac2e12b649abcb013
Cherry-pick eval_to_string_eap() from patch 8.2.1914.
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
-rw-r--r-- | src/nvim/eval.c | 24 | ||||
-rw-r--r-- | src/nvim/eval/vars.c | 2 | ||||
-rw-r--r-- | test/old/testdir/test_expr.vim | 12 | ||||
-rw-r--r-- | test/old/testdir/test_let.vim | 35 | ||||
-rw-r--r-- | test/old/testdir/test_put.vim | 8 |
5 files changed, 71 insertions, 10 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 6480d6e305..213948a028 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -969,13 +969,12 @@ int skip_expr(char **pp, evalarg_T *const evalarg) /// Convert "tv" to a string. /// -/// @param convert when true convert a List into a sequence of lines -/// and a Dict into a textual representation of the Dict. +/// @param join_list when true convert a List into a sequence of lines. /// /// @return an allocated string. -static char *typval2string(typval_T *tv, bool convert) +static char *typval2string(typval_T *tv, bool join_list) { - if (convert && tv->v_type == VAR_LIST) { + if (join_list && tv->v_type == VAR_LIST) { garray_T ga; ga_init(&ga, (int)sizeof(char), 80); if (tv->vval.v_list != NULL) { @@ -986,7 +985,7 @@ static char *typval2string(typval_T *tv, bool convert) } ga_append(&ga, NUL); return (char *)ga.ga_data; - } else if (convert && tv->v_type == VAR_DICT) { + } else if (tv->v_type == VAR_LIST || tv->v_type == VAR_DICT) { return encode_tv2string(tv, NULL); } return xstrdup(tv_get_string(tv)); @@ -994,18 +993,20 @@ static char *typval2string(typval_T *tv, bool convert) /// Top level evaluation function, returning a string. /// -/// @param convert when true convert a List into a sequence of lines. +/// @param join_list when true convert a List into a sequence of lines. /// /// @return pointer to allocated memory, or NULL for failure. -char *eval_to_string(char *arg, bool convert) +char *eval_to_string_eap(char *arg, bool join_list, exarg_T *eap) { typval_T tv; char *retval; - if (eval0(arg, &tv, NULL, &EVALARG_EVALUATE) == FAIL) { + evalarg_T evalarg; + fill_evalarg_from_eap(&evalarg, eap, eap != NULL && eap->skip); + if (eval0(arg, &tv, NULL, &evalarg) == FAIL) { retval = NULL; } else { - retval = typval2string(&tv, convert); + retval = typval2string(&tv, join_list); tv_clear(&tv); } clear_evalarg(&EVALARG_EVALUATE, NULL); @@ -1013,6 +1014,11 @@ char *eval_to_string(char *arg, bool convert) return retval; } +char *eval_to_string(char *arg, bool join_list) +{ + return eval_to_string_eap(arg, join_list, NULL); +} + /// Call eval_to_string() without using current local variables and using /// textlock. /// diff --git a/src/nvim/eval/vars.c b/src/nvim/eval/vars.c index 37199cd95d..1c15274acc 100644 --- a/src/nvim/eval/vars.c +++ b/src/nvim/eval/vars.c @@ -88,7 +88,7 @@ char *eval_one_expr_in_str(char *p, garray_T *gap, bool evaluate) } if (evaluate) { *block_end = NUL; - char *expr_val = eval_to_string(block_start, true); + char *expr_val = eval_to_string(block_start, false); *block_end = '}'; if (expr_val == NULL) { return NULL; diff --git a/test/old/testdir/test_expr.vim b/test/old/testdir/test_expr.vim index 82377aaf19..8871e7e7d7 100644 --- a/test/old/testdir/test_expr.vim +++ b/test/old/testdir/test_expr.vim @@ -907,6 +907,18 @@ func Test_string_interp() #" Dict interpolation VAR d = {'a': 10, 'b': [1, 2]} call assert_equal("{'a': 10, 'b': [1, 2]}", $'{d}') + VAR emptydict = {} + call assert_equal("a{}b", $'a{emptydict}b') + VAR nulldict = v:_null_dict + call assert_equal("a{}b", $'a{nulldict}b') + + #" List interpolation + VAR l = ['a', 'b', 'c'] + call assert_equal("['a', 'b', 'c']", $'{l}') + VAR emptylist = [] + call assert_equal("a[]b", $'a{emptylist}b') + VAR nulllist = v:_null_list + call assert_equal("a[]b", $'a{nulllist}b') #" Stray closing brace. call assert_fails('echo $"moo}"', 'E1278:') diff --git a/test/old/testdir/test_let.vim b/test/old/testdir/test_let.vim index 797cedcb07..d37af45aaa 100644 --- a/test/old/testdir/test_let.vim +++ b/test/old/testdir/test_let.vim @@ -694,6 +694,41 @@ END END call assert_equal(["let d2 = {'a': 10, 'b': 'ss', 'c': {}}"], code) + " Empty dictionary + let d1 = {} + let code =<< eval trim END + let d2 = {d1} + END + call assert_equal(["let d2 = {}"], code) + + " null dictionary + let d1 = v:_null_dict + let code =<< eval trim END + let d2 = {d1} + END + call assert_equal(["let d2 = {}"], code) + + " Evaluate a List + let l1 = ['a', 'b', 'c'] + let code =<< eval trim END + let l2 = {l1} + END + call assert_equal(["let l2 = ['a', 'b', 'c']"], code) + + " Empty List + let l1 = [] + let code =<< eval trim END + let l2 = {l1} + END + call assert_equal(["let l2 = []"], code) + + " Null List + let l1 = v:_null_list + let code =<< eval trim END + let l2 = {l1} + END + call assert_equal(["let l2 = []"], code) + let code = 'xxx' let code =<< eval trim END let n = {5 + diff --git a/test/old/testdir/test_put.vim b/test/old/testdir/test_put.vim index e01984228d..73b58dbe33 100644 --- a/test/old/testdir/test_put.vim +++ b/test/old/testdir/test_put.vim @@ -332,4 +332,12 @@ func Test_put_dict() bw! endfunc +func Test_put_list() + new + let l = ['a', 'b', 'c'] + put! =l + call assert_equal(['a', 'b', 'c', ''], getline(1, '$')) + bw! +endfunc + " vim: shiftwidth=2 sts=2 expandtab |