From e69cfe158a8c305cf3de0b8e056778cfd96d8c5f Mon Sep 17 00:00:00 2001 From: wsdjeg Date: Wed, 1 Mar 2017 17:03:26 +0800 Subject: [PATCH] Fix json api --- autoload/SpaceVim/api/data/json.vim | 104 +++++++++++++++++++++++----- 1 file changed, 88 insertions(+), 16 deletions(-) diff --git a/autoload/SpaceVim/api/data/json.vim b/autoload/SpaceVim/api/data/json.vim index 3d6532486..d7a0947c3 100644 --- a/autoload/SpaceVim/api/data/json.vim +++ b/autoload/SpaceVim/api/data/json.vim @@ -1,25 +1,97 @@ let s:json = {} -function! s:json_encode(expr) abort - " TODO - " support old vim version - return json_encode(a:expr) + +if exists('*json_decode') && 0 + let g:spacevim_api_json_true = v:true + let g:spacevim_api_json_true = v:false + let g:spacevim_api_json_true = v:null + function! s:json_decode(json) abort + if a:json ==# '' + return [] + endif + return json_decode(a:json) + endfunction +else + function! s:json_null() abort + endfunction + + function! s:json_true() abort + endfunction + + function! s:json_false() abort + endfunction + + let g:spacevim_api_json_true = [function('s:json_true')] + let g:spacevim_api_json_false = [function('s:json_false')] + let g:spacevim_api_json_null = [function('s:json_null')] + + function! s:json_decode(json) abort + let true = g:spacevim_api_json_true + let false = g:spacevim_api_json_false + let null = g:spacevim_api_json_null + if substitute(a:json, '\v\"%(\\.|[^"\\])*\"|true|false|null|[+-]?\d+%(\.\d+%([Ee][+-]?\d+)?)?', '', 'g') !~# "[^,:{}[\\] \t]" + + try + let object = eval(a:json) + catch + " malformed JSON + let object = '' + endtry + else + let object = '' + endif + + return object + endfunction +endif + +lockvar g:spacevim_api_json_true +lockvar g:spacevim_api_json_false +lockvar g:spacevim_api_json_null + +let s:json['json_decode'] = function('s:json_decode') + +function! s:json_encode(val) abort + if exists('*json_decode') && 0 + return json_encode(a:val) + else + if type(a:val) == type(0) + return a:val + elseif type(a:val) == type('') + let json = '"' . escape(a:val, '\"') . '"' + let json = substitute(json, "\r", '\\r', 'g') + let json = substitute(json, "\n", '\\n', 'g') + let json = substitute(json, "\t", '\\t', 'g') + let json = substitute(json, '\([[:cntrl:]]\)', '\=printf("\x%02d", char2nr(submatch(1)))', 'g') + return iconv(json, &encoding, 'utf-8') + elseif type(a:val) == 2 + let s = string(a:val) + if s == string(g:spacevim_api_json_null) + return 'null' + elseif s == string(g:spacevim_api_json_true) + return 'true' + elseif s == string(g:spacevim_api_json_false) + return 'false' + endif + elseif type(a:val) == type([]) + if len(a:val) == 1 && a:val[0] == g:spacevim_api_json_false[0] + return 'false' + elseif len(a:val) == 1 && a:val[0] == g:spacevim_api_json_true[0] + return 'true' + elseif len(a:val) == 1 && a:val[0] == g:spacevim_api_json_null[0] + return 'null' + endif + return '[' . join(map(copy(a:val), 's:json_encode(v:val)'), ',') . ']' + elseif type(a:val) == 4 + return '{' . join(map(keys(a:val), "s:json_encode(v:val) . ':' . s:json_encode(a:val[v:val])"), ',') . '}' + else + return string(a:val) + endif + endif endfunction let s:json['json_encode'] = function('s:json_encode') -function! s:json_decode(json) abort - if empty(a:json) && type(a:json) == type('') - return '' - endif - " TODO - " support old vim version - return json_decode(a:json) -endfunction - -let s:json['json_decode'] = function('s:json_decode') - - function! SpaceVim#api#data#json#get() abort return deepcopy(s:json) endfunction