diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-04-15 07:11:39 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-15 07:11:39 +0800 |
commit | 43f8d7e3ef2db733f01f2d4c03214cd90c5a09be (patch) | |
tree | 002e8a305a2217ce1b6f7f7ab7fef548fcd6b8b7 | |
parent | 7180ef690180cf92d1d49811820c46dd60e4d1c6 (diff) | |
download | rneovim-43f8d7e3ef2db733f01f2d4c03214cd90c5a09be.tar.gz rneovim-43f8d7e3ef2db733f01f2d4c03214cd90c5a09be.tar.bz2 rneovim-43f8d7e3ef2db733f01f2d4c03214cd90c5a09be.zip |
vim-patch:9.1.0329: String interpolation fails for Dict type (#28335)
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: vim/vim#14529
closes: vim/vim#14541
https://github.com/vim/vim/commit/f01493c55062c01b1cdf9b1e946577f4d1bdddf3
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
-rw-r--r-- | runtime/doc/builtin.txt | 8 | ||||
-rw-r--r-- | runtime/doc/change.txt | 4 | ||||
-rw-r--r-- | runtime/lua/vim/_meta/vimfn.lua | 8 | ||||
-rw-r--r-- | src/nvim/eval.c | 5 | ||||
-rw-r--r-- | src/nvim/eval.lua | 8 | ||||
-rw-r--r-- | test/functional/editor/mode_insert_spec.lua | 43 | ||||
-rw-r--r-- | test/functional/legacy/edit_spec.lua | 10 | ||||
-rw-r--r-- | test/old/testdir/test_edit.vim | 4 | ||||
-rw-r--r-- | test/old/testdir/test_expr.vim | 4 | ||||
-rw-r--r-- | test/old/testdir/test_let.vim | 7 | ||||
-rw-r--r-- | test/old/testdir/test_put.vim | 9 |
11 files changed, 62 insertions, 48 deletions
diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 36e433d1ec..94721f5024 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -7876,10 +7876,10 @@ string({expr}) *string()* for infinite and NaN floating-point values representations which use |str2float()|. Strings are also dumped literally, only single quote is escaped, which does not allow using YAML - for parsing back binary strings. |eval()| should always work for - strings and floats though and this is the only official - method, use |msgpackdump()| or |json_encode()| if you need to - share data with other application. + for parsing back binary strings. |eval()| should always work + for strings and floats though, and this is the only official + method. Use |msgpackdump()| or |json_encode()| if you need to + share data with other applications. strlen({string}) *strlen()* The result is a Number, which is the length of the String diff --git a/runtime/doc/change.txt b/runtime/doc/change.txt index 703addf51a..6d3efb4167 100644 --- a/runtime/doc/change.txt +++ b/runtime/doc/change.txt @@ -1291,8 +1291,8 @@ expression (like with the "/" command). The expression must evaluate to a String. A Number is always automatically converted to a String. For the "p" and ":put" command, if the result is a Float it's converted into a String. If the result is a List each element is -turned into a String and used as a line. A Dictionary or FuncRef results in -an error message (use string() to convert). +turned into a String and used as a line. A Dictionary is converted into a +String. A FuncRef results in an error message (use string() to convert). If the "= register is used for the "p" command, the String is split up at <NL> characters. If the String ends in a <NL>, it is regarded as a linewise diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index e3c7495cf9..d010673d24 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -9353,10 +9353,10 @@ function vim.fn.stridx(haystack, needle, start) end --- for infinite and NaN floating-point values representations --- which use |str2float()|. Strings are also dumped literally, --- only single quote is escaped, which does not allow using YAML ---- for parsing back binary strings. |eval()| should always work for ---- strings and floats though and this is the only official ---- method, use |msgpackdump()| or |json_encode()| if you need to ---- share data with other application. +--- for parsing back binary strings. |eval()| should always work +--- for strings and floats though, and this is the only official +--- method. Use |msgpackdump()| or |json_encode()| if you need to +--- share data with other applications. --- --- @param expr any --- @return string diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 10e9c3ea7f..6480d6e305 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -969,7 +969,8 @@ 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. +/// @param convert when true convert a List into a sequence of lines +/// and a Dict into a textual representation of the Dict. /// /// @return an allocated string. static char *typval2string(typval_T *tv, bool convert) @@ -985,6 +986,8 @@ 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) { + return encode_tv2string(tv, NULL); } return xstrdup(tv_get_string(tv)); } diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua index 388fd3a7cb..dcc8cf3c8c 100644 --- a/src/nvim/eval.lua +++ b/src/nvim/eval.lua @@ -11129,10 +11129,10 @@ M.funcs = { for infinite and NaN floating-point values representations which use |str2float()|. Strings are also dumped literally, only single quote is escaped, which does not allow using YAML - for parsing back binary strings. |eval()| should always work for - strings and floats though and this is the only official - method, use |msgpackdump()| or |json_encode()| if you need to - share data with other application. + for parsing back binary strings. |eval()| should always work + for strings and floats though, and this is the only official + method. Use |msgpackdump()| or |json_encode()| if you need to + share data with other applications. ]=], name = 'string', diff --git a/test/functional/editor/mode_insert_spec.lua b/test/functional/editor/mode_insert_spec.lua index aad92cb36a..6d075cdf36 100644 --- a/test/functional/editor/mode_insert_spec.lua +++ b/test/functional/editor/mode_insert_spec.lua @@ -52,43 +52,34 @@ describe('insert-mode', function() end) it('double quote is removed after hit-enter prompt #22609', function() - local screen = Screen.new(60, 6) - screen:set_default_attr_ids({ - [0] = { bold = true, foreground = Screen.colors.Blue }, -- NonText - [1] = { foreground = Screen.colors.Blue }, -- SpecialKey - [2] = { foreground = Screen.colors.SlateBlue }, - [3] = { bold = true }, -- ModeMsg - [4] = { reverse = true, bold = true }, -- MsgSeparator - [5] = { background = Screen.colors.Red, foreground = Screen.colors.White }, -- ErrorMsg - [6] = { foreground = Screen.colors.SeaGreen, bold = true }, -- MoreMsg - }) + local screen = Screen.new(50, 6) screen:attach() feed('i<C-R>') screen:expect([[ - {1:^"} | - {0:~ }|*4 - {3:-- INSERT --} | + {18:^"} | + {1:~ }|*4 + {5:-- INSERT --} | ]]) - feed('={}') + feed("=function('add')") screen:expect([[ - {1:"} | - {0:~ }|*4 - ={2:{}}^ | + {18:"} | + {1:~ }|*4 + ={25:function}{16:(}{26:'add'}{16:)}^ | ]]) feed('<CR>') screen:expect([[ - {1:"} | - {0:~ }| - {4: }| - ={2:{}} | - {5:E731: Using a Dictionary as a String} | - {6:Press ENTER or type command to continue}^ | + {18:"} | + {1:~ }| + {3: }| + ={25:function}{16:(}{26:'add'}{16:)} | + {9:E729: Using a Funcref as a String} | + {6:Press ENTER or type command to continue}^ | ]]) feed('<CR>') screen:expect([[ - ^ | - {0:~ }|*4 - {3:-- INSERT --} | + ^ | + {1:~ }|*4 + {5:-- INSERT --} | ]]) end) end) diff --git a/test/functional/legacy/edit_spec.lua b/test/functional/legacy/edit_spec.lua index c79213656f..0def49b85d 100644 --- a/test/functional/legacy/edit_spec.lua +++ b/test/functional/legacy/edit_spec.lua @@ -56,20 +56,20 @@ describe('edit', function() {1:~ }|*4 {5:-- INSERT --} | ]]) - feed('={}') + feed('=0z') screen:expect([[ {18:"} | {1:~ }|*4 - ={16:{}}^ | + ={26:0}{9:z}^ | ]]) - -- trying to insert a dictionary produces an error + -- trying to insert a blob produces an error feed('<CR>') screen:expect([[ {18:"} | {1:~ }| {3: }| - ={16:{}} | - {9:E731: Using a Dictionary as a String} | + ={26:0}{9:z} | + {9:E976: Using a Blob as a String} | {6:Press ENTER or type command to continue}^ | ]]) diff --git a/test/old/testdir/test_edit.vim b/test/old/testdir/test_edit.vim index abd30074d5..57ff63f26d 100644 --- a/test/old/testdir/test_edit.vim +++ b/test/old/testdir/test_edit.vim @@ -1983,8 +1983,8 @@ func Test_edit_ctrl_r_failed() let buf = RunVimInTerminal('', #{rows: 6, cols: 60}) - " trying to insert a dictionary produces an error - call term_sendkeys(buf, "i\<C-R>={}\<CR>") + " trying to insert a blob produces an error + call term_sendkeys(buf, "i\<C-R>=0z\<CR>") " ending Insert mode should put the cursor back on the ':' call term_sendkeys(buf, ":\<Esc>") diff --git a/test/old/testdir/test_expr.vim b/test/old/testdir/test_expr.vim index d316e63818..82377aaf19 100644 --- a/test/old/testdir/test_expr.vim +++ b/test/old/testdir/test_expr.vim @@ -904,6 +904,10 @@ func Test_string_interp() endif call assert_equal(0, tmp) + #" Dict interpolation + VAR d = {'a': 10, 'b': [1, 2]} + call assert_equal("{'a': 10, 'b': [1, 2]}", $'{d}') + #" Stray closing brace. call assert_fails('echo $"moo}"', 'E1278:') #" Undefined variable in expansion. diff --git a/test/old/testdir/test_let.vim b/test/old/testdir/test_let.vim index bdf08c29bf..797cedcb07 100644 --- a/test/old/testdir/test_let.vim +++ b/test/old/testdir/test_let.vim @@ -687,6 +687,13 @@ END END call assert_equal(['let a = {abc}', 'let b = X', 'let c = {'], code) + " Evaluate a dictionary + let d1 = #{a: 10, b: 'ss', c: {}} + let code =<< eval trim END + let d2 = {d1} + END + call assert_equal(["let d2 = {'a': 10, 'b': 'ss', 'c': {}}"], 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 b1cf268a58..e01984228d 100644 --- a/test/old/testdir/test_put.vim +++ b/test/old/testdir/test_put.vim @@ -323,4 +323,13 @@ func Test_put_visual_replace_fold_marker() bwipe! endfunc +func Test_put_dict() + new + let d = #{a: #{b: 'abc'}, c: [1, 2], d: 0z10} + put! =d + call assert_equal(["{'a': {'b': 'abc'}, 'c': [1, 2], 'd': 0z10}", ''], + \ getline(1, '$')) + bw! +endfunc + " vim: shiftwidth=2 sts=2 expandtab |