Last active
January 15, 2021 16:59
-
-
Save wordijp/42645dd9b6d3bb517aed0385afbbb51d to your computer and use it in GitHub Desktop.
VimScriptの変数をJSON化してインタラクティブに確認する
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
" 変数をJSON化(非可逆)して、インタラクティブに確認出来る jid コマンドを使って確認する | |
" use) call Jid({'hello': 'world', 'age': 17}) | |
" ターミナル版 | |
function! Jid(dic) | |
call s:_jid_core(a:dic, 0) | |
endfunction | |
" ポップアップ版 | |
" NOTE: 1つまで、2つ以上同時に出すとエラーになる | |
function! Jid_popup(dic) | |
call s:_jid_core(a:dic, 1) | |
endfunction | |
" --- | |
function! s:_jid_core(dic, popup) | |
let l:temp = tempname() | |
execute ":redir! > " . l:temp | |
silent! echon s:_json_encode_irreversible(0, a:dic) | |
redir END | |
" NOTE: popup化する時はterm_startでhidden: 1 | |
let l:id = term_start([&shell], #{ hidden: a:popup ? 1 : 0, term_finish: 'close' }) | |
call term_sendkeys(l:id, "cat ".l:temp." | jid -M\<CR>") | |
if a:popup | |
call popup_create(l:id, #{ border: [], minwidth: winwidth(0)/2, minheight: &lines/2 }) | |
endif | |
endfunction | |
" JSON化(非可逆)する | |
" NOTE: json_encodeはFuncrefやchannelなどが非対応なので、自前でJSON化 | |
" 確認用にしか使わないのでそれっぽく見れればおk | |
" original) https://github.com/mattn/webapi-vim/blob/master/autoload/webapi/json.vim :webapi#json#encode() | |
function! s:_json_encode_irreversible(depth, val) abort | |
if type(a:val) == 0 | |
return a:val | |
elseif type(a:val) == 1 | |
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") | |
"return json_encode(a:val) | |
elseif type(a:val) == 2 | |
return '"' . s:string_fn(a:val) . '"' | |
elseif type(a:val) == 3 | |
if a:depth > 7 | return '["%%MAX_DEPTH%%:' . a:depth . '"]' | endif | |
return '[' . join(map(copy(a:val), 's:_json_encode_irreversible(a:depth+1, v:val)'), ',') . ']' | |
elseif type(a:val) == 4 | |
" NOTE: 深すぎるとmaxfuncdepthを超えるエラーが出る | |
if a:depth > 7 | return '{"%%MAX_DEPTH%%":' . a:depth . '}' | endif | |
return '{' . join(map(keys(a:val), 's:_json_encode_irreversible(a:depth+1, v:val).":".s:_json_encode_irreversible(a:depth+1, a:val[v:val])'), ',') . '}' | |
elseif type(a:val) == 5 | |
return a:val | |
elseif type(a:val) == 6 | |
if a:val == v:true | |
return 'true' | |
elseif a:val == v:false | |
return 'false' | |
endif | |
throw 'unknown type 5 value:'.string(a:val) | |
elseif type(a:val) == 7 | |
if a:val == v:null | |
return 'null' | |
elseif a:val == v:none | |
return '"v:none"' | |
endif | |
throw 'unknown type 7 value:'.string(a:val) | |
elseif type(a:val) == 8 | |
return '"' . "job('" . string(a:val) . "')" . '"' | |
elseif type(a:val) == 9 | |
return '"' . "ch('" . string(a:val) . "')" . '"' | |
elseif type(a:val) == 10 | |
return '"' . "blob('" . string(a:val). "')" . '"' | |
else | |
throw 'unknown type:'.type(a:val) | |
endif | |
endfunction | |
function! s:string_fn(fn) | |
let l:sfn = string(a:fn) | |
let l:start = stridx(l:sfn, "'") | |
let l:end = l:start+1 + stridx(l:sfn[l:start+1:], "'") | |
if l:sfn[l:end:] == "')" | |
return l:sfn | |
else | |
" NOTE: 長いと見辛いので省略 | |
return l:sfn[:l:end] . ', ...)' | |
endif | |
endfunction |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment