Skip to content

Commit f01493c

Browse files
yegappanchrisbra
authored andcommitted
patch 9.1.0329: String interpolation fails for Dict type
Problem: String interpolation fails for Dict type Solution: Support Dict data type properly, also support :put =Dict (without having to convert it to string() first) (Yegappan Lakshmanan) fixes: #14529 closes: #14541 Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
1 parent 0d87e3c commit f01493c

10 files changed

Lines changed: 43 additions & 7 deletions

File tree

runtime/doc/change.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*change.txt* For Vim version 9.1. Last change: 2023 Dec 19
1+
*change.txt* For Vim version 9.1. Last change: 2024 Apr 14
22

33

44
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -1345,8 +1345,8 @@ expression (like with the "/" command).
13451345
The expression must evaluate to a String. A Number is always automatically
13461346
converted to a String. For the "p" and ":put" command, if the result is a
13471347
Float it's converted into a String. If the result is a List each element is
1348-
turned into a String and used as a line. A Dictionary or FuncRef results in
1349-
an error message (use string() to convert).
1348+
turned into a String and used as a line. A Dictionary is converted into a
1349+
String. A FuncRef results in an error message (use string() to convert).
13501350

13511351
If the "= register is used for the "p" command, the String is split up at <NL>
13521352
characters. If the String ends in a <NL>, it is regarded as a linewise

src/eval.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,8 @@ skip_expr_concatenate(
575575

576576
/*
577577
* Convert "tv" to a string.
578-
* When "convert" is TRUE convert a List into a sequence of lines.
578+
* When "convert" is TRUE convert a List into a sequence of lines and a Dict
579+
* into a textual representation of the Dict.
579580
* Returns an allocated string (NULL when out of memory).
580581
*/
581582
char_u *
@@ -596,6 +597,8 @@ typval2string(typval_T *tv, int convert)
596597
ga_append(&ga, NUL);
597598
retval = (char_u *)ga.ga_data;
598599
}
600+
else if (convert && tv->v_type == VAR_DICT)
601+
retval = dict2string(tv, get_copyID(), FALSE);
599602
else
600603
retval = vim_strsave(tv_get_string(tv));
601604
return retval;

src/testdir/test_edit.vim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1962,8 +1962,8 @@ func Test_edit_ctrl_r_failed()
19621962

19631963
let buf = RunVimInTerminal('', #{rows: 6, cols: 60})
19641964

1965-
" trying to insert a dictionary produces an error
1966-
call term_sendkeys(buf, "i\<C-R>={}\<CR>")
1965+
" trying to insert a blob produces an error
1966+
call term_sendkeys(buf, "i\<C-R>=0z\<CR>")
19671967

19681968
" ending Insert mode should put the cursor back on the ':'
19691969
call term_sendkeys(buf, ":\<Esc>")

src/testdir/test_expr.vim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -950,6 +950,10 @@ func Test_string_interp()
950950
endif
951951
call assert_equal(0, tmp)
952952

953+
#" Dict interpolation
954+
VAR d = {'a': 10, 'b': [1, 2]}
955+
call assert_equal("{'a': 10, 'b': [1, 2]}", $'{d}')
956+
953957
#" Stray closing brace.
954958
call assert_fails('echo $"moo}"', 'E1278:')
955959
#" Undefined variable in expansion.

src/testdir/test_let.vim

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,13 @@ END
689689
END
690690
call assert_equal(['let a = {abc}', 'let b = X', 'let c = {'], code)
691691

692+
" Evaluate a dictionary
693+
let d1 = #{a: 10, b: 'ss', c: {}}
694+
let code =<< eval trim END
695+
let d2 = {d1}
696+
END
697+
call assert_equal(["let d2 = {'a': 10, 'b': 'ss', 'c': {}}"], code)
698+
692699
let code = 'xxx'
693700
let code =<< eval trim END
694701
let n = {5 +

src/testdir/test_put.vim

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,4 +319,13 @@ func Test_put_visual_replace_fold_marker()
319319
bwipe!
320320
endfunc
321321

322+
func Test_put_dict()
323+
new
324+
let d = #{a: #{b: 'abc'}, c: [1, 2], d: 0z10}
325+
put! =d
326+
call assert_equal(["{'a': {'b': 'abc'}, 'c': [1, 2], 'd': 0z10}", ''],
327+
\ getline(1, '$'))
328+
bw!
329+
endfunc
330+
322331
" vim: shiftwidth=2 sts=2 expandtab

src/testdir/test_vim9_assign.vim

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2984,6 +2984,16 @@ def Test_heredoc_expr()
29842984
CODE
29852985
v9.CheckDefAndScriptSuccess(lines)
29862986

2987+
# Evaluate a dictionary
2988+
lines =<< trim CODE
2989+
var d1 = {'a': 10, 'b': [1, 2]}
2990+
var code =<< trim eval END
2991+
var d2 = {d1}
2992+
END
2993+
assert_equal(["var d2 = {'a': 10, 'b': [1, 2]}"], code)
2994+
CODE
2995+
v9.CheckDefAndScriptSuccess(lines)
2996+
29872997
lines =<< trim CODE
29882998
var code =<< eval trim END
29892999
var s = "{$SOME_ENV_VAR}"

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,8 @@ static char *(features[]) =
704704

705705
static int included_patches[] =
706706
{ /* Add new patch number below this line */
707+
/**/
708+
329,
707709
/**/
708710
328,
709711
/**/

src/vim9execute.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1653,6 +1653,7 @@ do_2string(typval_T *tv, int is_2string_any, int tolerant)
16531653
case VAR_BOOL:
16541654
case VAR_NUMBER:
16551655
case VAR_FLOAT:
1656+
case VAR_DICT:
16561657
case VAR_BLOB: break;
16571658

16581659
case VAR_LIST:

src/vim9instr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ may_generate_2STRING(int offset, int tolerant, cctx_T *cctx)
222222

223223
// conversion possible when tolerant
224224
case VAR_LIST:
225+
case VAR_DICT:
225226
if (tolerant)
226227
{
227228
isntype = ISN_2STRING_ANY;
@@ -234,7 +235,6 @@ may_generate_2STRING(int offset, int tolerant, cctx_T *cctx)
234235
case VAR_BLOB:
235236
case VAR_FUNC:
236237
case VAR_PARTIAL:
237-
case VAR_DICT:
238238
case VAR_JOB:
239239
case VAR_CHANNEL:
240240
case VAR_INSTR:

0 commit comments

Comments
 (0)