mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
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
f01493c550
Co-authored-by: Yegappan Lakshmanan <yegappan@yahoo.com>
This commit is contained in:
parent
7180ef6901
commit
43f8d7e3ef
8
runtime/doc/builtin.txt
generated
8
runtime/doc/builtin.txt
generated
@ -7876,10 +7876,10 @@ string({expr}) *string()*
|
|||||||
for infinite and NaN floating-point values representations
|
for infinite and NaN floating-point values representations
|
||||||
which use |str2float()|. Strings are also dumped literally,
|
which use |str2float()|. Strings are also dumped literally,
|
||||||
only single quote is escaped, which does not allow using YAML
|
only single quote is escaped, which does not allow using YAML
|
||||||
for parsing back binary strings. |eval()| should always work for
|
for parsing back binary strings. |eval()| should always work
|
||||||
strings and floats though and this is the only official
|
for strings and floats though, and this is the only official
|
||||||
method, use |msgpackdump()| or |json_encode()| if you need to
|
method. Use |msgpackdump()| or |json_encode()| if you need to
|
||||||
share data with other application.
|
share data with other applications.
|
||||||
|
|
||||||
strlen({string}) *strlen()*
|
strlen({string}) *strlen()*
|
||||||
The result is a Number, which is the length of the String
|
The result is a Number, which is the length of the String
|
||||||
|
@ -1291,8 +1291,8 @@ expression (like with the "/" command).
|
|||||||
The expression must evaluate to a String. A Number is always automatically
|
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
|
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
|
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
|
turned into a String and used as a line. A Dictionary is converted into a
|
||||||
an error message (use string() to convert).
|
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>
|
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
|
characters. If the String ends in a <NL>, it is regarded as a linewise
|
||||||
|
8
runtime/lua/vim/_meta/vimfn.lua
generated
8
runtime/lua/vim/_meta/vimfn.lua
generated
@ -9353,10 +9353,10 @@ function vim.fn.stridx(haystack, needle, start) end
|
|||||||
--- for infinite and NaN floating-point values representations
|
--- for infinite and NaN floating-point values representations
|
||||||
--- which use |str2float()|. Strings are also dumped literally,
|
--- which use |str2float()|. Strings are also dumped literally,
|
||||||
--- only single quote is escaped, which does not allow using YAML
|
--- only single quote is escaped, which does not allow using YAML
|
||||||
--- for parsing back binary strings. |eval()| should always work for
|
--- for parsing back binary strings. |eval()| should always work
|
||||||
--- strings and floats though and this is the only official
|
--- for strings and floats though, and this is the only official
|
||||||
--- method, use |msgpackdump()| or |json_encode()| if you need to
|
--- method. Use |msgpackdump()| or |json_encode()| if you need to
|
||||||
--- share data with other application.
|
--- share data with other applications.
|
||||||
---
|
---
|
||||||
--- @param expr any
|
--- @param expr any
|
||||||
--- @return string
|
--- @return string
|
||||||
|
@ -969,7 +969,8 @@ int skip_expr(char **pp, evalarg_T *const evalarg)
|
|||||||
|
|
||||||
/// Convert "tv" to a string.
|
/// 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.
|
/// @return an allocated string.
|
||||||
static char *typval2string(typval_T *tv, bool convert)
|
static char *typval2string(typval_T *tv, bool convert)
|
||||||
@ -985,6 +986,8 @@ static char *typval2string(typval_T *tv, bool convert)
|
|||||||
}
|
}
|
||||||
ga_append(&ga, NUL);
|
ga_append(&ga, NUL);
|
||||||
return (char *)ga.ga_data;
|
return (char *)ga.ga_data;
|
||||||
|
} else if (convert && tv->v_type == VAR_DICT) {
|
||||||
|
return encode_tv2string(tv, NULL);
|
||||||
}
|
}
|
||||||
return xstrdup(tv_get_string(tv));
|
return xstrdup(tv_get_string(tv));
|
||||||
}
|
}
|
||||||
|
@ -11129,10 +11129,10 @@ M.funcs = {
|
|||||||
for infinite and NaN floating-point values representations
|
for infinite and NaN floating-point values representations
|
||||||
which use |str2float()|. Strings are also dumped literally,
|
which use |str2float()|. Strings are also dumped literally,
|
||||||
only single quote is escaped, which does not allow using YAML
|
only single quote is escaped, which does not allow using YAML
|
||||||
for parsing back binary strings. |eval()| should always work for
|
for parsing back binary strings. |eval()| should always work
|
||||||
strings and floats though and this is the only official
|
for strings and floats though, and this is the only official
|
||||||
method, use |msgpackdump()| or |json_encode()| if you need to
|
method. Use |msgpackdump()| or |json_encode()| if you need to
|
||||||
share data with other application.
|
share data with other applications.
|
||||||
|
|
||||||
]=],
|
]=],
|
||||||
name = 'string',
|
name = 'string',
|
||||||
|
@ -52,43 +52,34 @@ describe('insert-mode', function()
|
|||||||
end)
|
end)
|
||||||
|
|
||||||
it('double quote is removed after hit-enter prompt #22609', function()
|
it('double quote is removed after hit-enter prompt #22609', function()
|
||||||
local screen = Screen.new(60, 6)
|
local screen = Screen.new(50, 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
|
|
||||||
})
|
|
||||||
screen:attach()
|
screen:attach()
|
||||||
feed('i<C-R>')
|
feed('i<C-R>')
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
{1:^"} |
|
{18:^"} |
|
||||||
{0:~ }|*4
|
{1:~ }|*4
|
||||||
{3:-- INSERT --} |
|
{5:-- INSERT --} |
|
||||||
]])
|
]])
|
||||||
feed('={}')
|
feed("=function('add')")
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
{1:"} |
|
{18:"} |
|
||||||
{0:~ }|*4
|
{1:~ }|*4
|
||||||
={2:{}}^ |
|
={25:function}{16:(}{26:'add'}{16:)}^ |
|
||||||
]])
|
]])
|
||||||
feed('<CR>')
|
feed('<CR>')
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
{1:"} |
|
{18:"} |
|
||||||
{0:~ }|
|
{1:~ }|
|
||||||
{4: }|
|
{3: }|
|
||||||
={2:{}} |
|
={25:function}{16:(}{26:'add'}{16:)} |
|
||||||
{5:E731: Using a Dictionary as a String} |
|
{9:E729: Using a Funcref as a String} |
|
||||||
{6:Press ENTER or type command to continue}^ |
|
{6:Press ENTER or type command to continue}^ |
|
||||||
]])
|
]])
|
||||||
feed('<CR>')
|
feed('<CR>')
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
^ |
|
^ |
|
||||||
{0:~ }|*4
|
{1:~ }|*4
|
||||||
{3:-- INSERT --} |
|
{5:-- INSERT --} |
|
||||||
]])
|
]])
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
@ -56,20 +56,20 @@ describe('edit', function()
|
|||||||
{1:~ }|*4
|
{1:~ }|*4
|
||||||
{5:-- INSERT --} |
|
{5:-- INSERT --} |
|
||||||
]])
|
]])
|
||||||
feed('={}')
|
feed('=0z')
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
{18:"} |
|
{18:"} |
|
||||||
{1:~ }|*4
|
{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>')
|
feed('<CR>')
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
{18:"} |
|
{18:"} |
|
||||||
{1:~ }|
|
{1:~ }|
|
||||||
{3: }|
|
{3: }|
|
||||||
={16:{}} |
|
={26:0}{9:z} |
|
||||||
{9:E731: Using a Dictionary as a String} |
|
{9:E976: Using a Blob as a String} |
|
||||||
{6:Press ENTER or type command to continue}^ |
|
{6:Press ENTER or type command to continue}^ |
|
||||||
]])
|
]])
|
||||||
|
|
||||||
|
@ -1983,8 +1983,8 @@ func Test_edit_ctrl_r_failed()
|
|||||||
|
|
||||||
let buf = RunVimInTerminal('', #{rows: 6, cols: 60})
|
let buf = RunVimInTerminal('', #{rows: 6, cols: 60})
|
||||||
|
|
||||||
" trying to insert a dictionary produces an error
|
" trying to insert a blob produces an error
|
||||||
call term_sendkeys(buf, "i\<C-R>={}\<CR>")
|
call term_sendkeys(buf, "i\<C-R>=0z\<CR>")
|
||||||
|
|
||||||
" ending Insert mode should put the cursor back on the ':'
|
" ending Insert mode should put the cursor back on the ':'
|
||||||
call term_sendkeys(buf, ":\<Esc>")
|
call term_sendkeys(buf, ":\<Esc>")
|
||||||
|
@ -904,6 +904,10 @@ func Test_string_interp()
|
|||||||
endif
|
endif
|
||||||
call assert_equal(0, tmp)
|
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.
|
#" Stray closing brace.
|
||||||
call assert_fails('echo $"moo}"', 'E1278:')
|
call assert_fails('echo $"moo}"', 'E1278:')
|
||||||
#" Undefined variable in expansion.
|
#" Undefined variable in expansion.
|
||||||
|
@ -687,6 +687,13 @@ END
|
|||||||
END
|
END
|
||||||
call assert_equal(['let a = {abc}', 'let b = X', 'let c = {'], code)
|
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 = 'xxx'
|
||||||
let code =<< eval trim END
|
let code =<< eval trim END
|
||||||
let n = {5 +
|
let n = {5 +
|
||||||
|
@ -323,4 +323,13 @@ func Test_put_visual_replace_fold_marker()
|
|||||||
bwipe!
|
bwipe!
|
||||||
endfunc
|
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
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
Loading…
Reference in New Issue
Block a user