From bda63d5b97dfb333de6f4bd757dbb978906062a2 Mon Sep 17 00:00:00 2001 From: bfredl Date: Tue, 25 Jun 2024 15:33:47 +0200 Subject: refactor(typval)!: remove distinction of binary and nonbinary strings This is a breaking change which will make refactor of typval and shada code a lot easier. In particular, code that would use or check for v:msgpack_types.binary in the wild would be broken. This appears to be rarely used in existing plugins. Also some cases where v:msgpack_type.string would be used to represent a binary string of "string" type, we use a BLOB instead, which is vimscripts native type for binary blobs, and already was used for BIN formats when necessary. msgpackdump(msgpackparse(data)) no longer preserves the distinction of BIN and STR strings. This is very common behavior for language-specific msgpack bindings. Nvim uses msgpack as a tool to serialize its data. Nvim is not a tool to bit-perfectly manipulate arbitrary msgpack data out in the wild. The changed tests should indicate how behavior changes in various edge cases. --- runtime/autoload/msgpack.vim | 50 ++++++++++++++++++++--------------------- runtime/autoload/shada.vim | 4 ++-- runtime/doc/builtin.txt | 7 +----- runtime/doc/news.txt | 6 +++++ runtime/lua/vim/_meta/vimfn.lua | 7 +----- 5 files changed, 34 insertions(+), 40 deletions(-) (limited to 'runtime') diff --git a/runtime/autoload/msgpack.vim b/runtime/autoload/msgpack.vim index 18dcd1e6a6..fb438def4f 100644 --- a/runtime/autoload/msgpack.vim +++ b/runtime/autoload/msgpack.vim @@ -361,7 +361,7 @@ endfunction let s:MSGPACK_STANDARD_TYPES = { \type(0): 'integer', \type(0.0): 'float', - \type(''): 'binary', + \type(''): 'string', \type([]): 'array', \type({}): 'map', \type(v:true): 'boolean', @@ -412,9 +412,15 @@ endfunction "" " Dump |msgpack-special-dict| that represents a string. If any additional " parameter is given then it dumps binary string. -function s:msgpack_dump_string(v, ...) abort - let ret = [a:0 ? '"' : '="'] - for v in a:v._VAL +function s:msgpack_dump_string(v) abort + if type(a:v) == type({}) + let val = a:v + else + let val = {'_VAL': split(a:v, "\n", 1)} + end + + let ret = ['"'] + for v in val._VAL call add( \ret, \substitute( @@ -426,16 +432,6 @@ function s:msgpack_dump_string(v, ...) abort return join(ret, '') endfunction -"" -" Dump binary string. -function s:msgpack_dump_binary(v) abort - if type(a:v) == type({}) - return s:msgpack_dump_string(a:v, 1) - else - return s:msgpack_dump_string({'_VAL': split(a:v, "\n", 1)}, 1) - endif -endfunction - "" " Dump array value. function s:msgpack_dump_array(v) abort @@ -449,7 +445,7 @@ function s:msgpack_dump_map(v) abort let ret = ['{'] if msgpack#special_type(a:v) is 0 for [k, v] in items(a:v) - let ret += [s:msgpack_dump_string({'_VAL': split(k, "\n", 1)}), + let ret += [s:msgpack_dump_string({'_VAL': split(k, "\n")}), \': ', \msgpack#string(v), \', '] @@ -479,7 +475,7 @@ endfunction " Dump extension value. function s:msgpack_dump_ext(v) abort return printf('+(%i)%s', a:v._VAL[0], - \s:msgpack_dump_string({'_VAL': a:v._VAL[1]}, 1)) + \s:msgpack_dump_string({'_VAL': a:v._VAL[1]})) endfunction "" @@ -619,9 +615,7 @@ function msgpack#eval(s, special_objs) abort throw '"-invalid:Invalid string: ' . s endif call add(expr, '{''_TYPE'': v:msgpack_types.') - if empty(match[1]) - call add(expr, 'binary') - elseif match[1] is# '=' + if empty(match[1]) || match[1] is# '=' call add(expr, 'string') else call add(expr, 'ext') @@ -772,7 +766,7 @@ function msgpack#equal(a, b) let a = aspecial is 0 ? a:a : a:a._VAL let b = bspecial is 0 ? a:b : a:b._VAL return msgpack#equal(a, b) - elseif atype is# 'binary' + elseif atype is# 'string' let a = (aspecial is 0 ? split(a:a, "\n", 1) : a:a._VAL) let b = (bspecial is 0 ? split(a:b, "\n", 1) : a:b._VAL) return a ==# b @@ -787,13 +781,17 @@ function msgpack#equal(a, b) " Non-special mapping cannot have non-string keys return 0 endif - if (empty(k._VAL) - \|| k._VAL ==# [""] - \|| !empty(filter(copy(k._VAL), 'stridx(v:val, "\n") != -1'))) - " Non-special mapping cannot have zero byte in key or an empty key - return 0 + if type(k) == type({}) + if (empty(k._VAL) + \|| k._VAL ==# [""] + \|| !empty(filter(copy(k._VAL), 'stridx(v:val, "\n") != -1'))) + " Non-special mapping cannot have zero byte in key or an empty key + return 0 + endif + let kstr = join(k._VAL, "\n") + else + let kstr = k endif - let kstr = join(k._VAL, "\n") if !has_key(akeys, kstr) " Protects from both missing and duplicate keys return 0 diff --git a/runtime/autoload/shada.vim b/runtime/autoload/shada.vim index ae718ad2e7..4753973196 100644 --- a/runtime/autoload/shada.vim +++ b/runtime/autoload/shada.vim @@ -230,7 +230,7 @@ function s:shada_check_type(type, val) abort return 0 elseif a:type is# 'bin' " Binary string without zero bytes - if type isnot# 'binary' + if type isnot# 'string' return 'Expected binary string' elseif (type(a:val) == type({}) \&& !empty(filter(copy(a:val._VAL), 'stridx(v:val, "\n") != -1'))) @@ -247,7 +247,7 @@ function s:shada_check_type(type, val) abort if type isnot# 'array' return 'Expected array value' elseif !empty(filter(copy(type(a:val) == type({}) ? a:val._VAL : a:val), - \'msgpack#type(v:val) isnot# "binary"')) + \'msgpack#type(v:val) isnot# "string"')) return 'Expected array of binary strings' else for element in (type(a:val) == type({}) ? a:val._VAL : a:val) diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 1e0df1918b..180d308ef5 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -5152,12 +5152,7 @@ msgpackparse({data}) *msgpackparse()* C parser does not support such values. float |Float|. This value cannot possibly appear in |msgpackparse()| output. - string |readfile()|-style list of strings. This value will - appear in |msgpackparse()| output if string contains - zero byte or if string is a mapping key and mapping is - being represented as special dictionary for other - reasons. - binary |String|, or |Blob| if binary string contains zero + string |String|, or |Blob| if binary string contains zero byte. This value cannot appear in |msgpackparse()| output since blobs were introduced. array |List|. This value cannot appear in |msgpackparse()| diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index 38be234b00..f1c241a951 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -50,6 +50,12 @@ EDITOR • |hl-CurSearch| now behaves the same as Vim and no longer updates on every cursor movement. +VIM SCRIPT + +• |v:msgpack_types| has the type "binary" removed. |msgpackparse()| no longer + treats BIN, STR and FIXSTR as separate types. Any of these is returned as a + string if possible, or a |blob| if the value contained embedded NUL:s. + EVENTS • TODO diff --git a/runtime/lua/vim/_meta/vimfn.lua b/runtime/lua/vim/_meta/vimfn.lua index 11dcbc010b..9d4cc825ec 100644 --- a/runtime/lua/vim/_meta/vimfn.lua +++ b/runtime/lua/vim/_meta/vimfn.lua @@ -6177,12 +6177,7 @@ function vim.fn.msgpackdump(list, type) end --- C parser does not support such values. --- float |Float|. This value cannot possibly appear in --- |msgpackparse()| output. ---- string |readfile()|-style list of strings. This value will ---- appear in |msgpackparse()| output if string contains ---- zero byte or if string is a mapping key and mapping is ---- being represented as special dictionary for other ---- reasons. ---- binary |String|, or |Blob| if binary string contains zero +--- string |String|, or |Blob| if binary string contains zero --- byte. This value cannot appear in |msgpackparse()| --- output since blobs were introduced. --- array |List|. This value cannot appear in |msgpackparse()| -- cgit