Skip to content

Instantly share code, notes, and snippets.

@hayajo
Created July 13, 2012 04:52
Show Gist options
  • Save hayajo/3102792 to your computer and use it in GitHub Desktop.
Save hayajo/3102792 to your computer and use it in GitHub Desktop.
VimでJSON
scriptencoding utf-8
"{{{ curlオプション
if exists('s:curl_opts')
unlet s:curl_opts
endif
let s:curl_opts = "-s -k"
"}}}
"{{{ JSONを取得
" e.g) :GetJson('url'[, 'user', 'pass' ])
function! GetJson(url, ...)
let curl_opts = s:curl_opts " s:curl_optsをコピー
" 認証オプション設定
if a:0 > 0
let user = a:1
" パスワードの指定がない場合は入力プロンプトを表示
if (a:0 != 2)
let passwd = inputsecret('Password: ')
endif
" 認証オプションを設定
let curl_opts = printf('%s -u %s:%s', curl_opts, user, passwd)
endif
let cmd_curl = printf('curl %s "%s"', curl_opts, a:url)
let json = system(cmd_curl)
return DecodeJson(json)
endfunction
"}}}
"{{{ JSONデータをスクリプトで扱えるようにデコード
function! DecodeJson(json) abort
" vimにない値を定義
let true = 1
let false = 0
let null = []
" 現在の文字エンコーディング設定を退避
let org_enc = &encoding
let &encoding = 'utf-8'
" unicodeエスケープからunicode文字に変換
let utf8_json = substitute(a:json, '\\u\([0-9a-zA-Z]\{4\}\)', '\=nr2char("0x".submatch(1))', 'g')
" 改行を削除しておかないと:executeでsyntax errorになる
let utf8_json = substitute(utf8_json, '\n', '', 'g')
" ここね、ここ。ここ重要よー。
" 取得したJSON文字列(utf-8からもとの文字エンコーディングに変換済)をeval(execute)してるのよー。
exe 'let decoded_json = ' . iconv(utf8_json, 'utf-8', org_enc)
" 文字エンコーディング設定をもとに戻す
let &encoding = org_enc
return decoded_json
endfunction
" FIXME: 展開されるJSON文字列が長すぎるとexecuteのハンドラ実行部分で"E15: Invalid expression:"になる?
" e.g) :GetJsonP('url'[, 'callback', 'user', 'pass' ])
function! GetJsonP(url, ...)
let args = deepcopy(a:000)
let sep = stridx(a:url, '?') == -1 ? '?' : '&'
let handler = (a:0 > 0 && a:1 != '') ? remove(args, 0) : 'JsonHandler'
let url = a:url . sep . 'callback=' . handler
return call('GetJson', [ url ] + args)
endfunction
function! JsonHandler(data)
return a:data
endfunction
"}}}
" GetJson: JSONデータをダンプ(要 thinca/vim-prettyprint)
" e.g) :GetJson 'url'[, 'user' ]
command! -nargs=+ GetJson :echo PP(GetJson(<args>))
" FIXME: GetJsonP: JSONデータをダンプ(要 thinca/vim-prettyprint)
" e.g) :GetJsonP 'url'[, 'callback', 'user' ]
command! -nargs=+ GetJsonP :echo PP(GetJsonP(<args>))
"{{{ サンプル
"{{{ UTIL: URLエンコード
function! s:url_encode_char(c)
let utf8 = iconv(a:c, &encoding, 'utf-8')
if utf8 == ""
let utf8 = a:c
endif
let encoded = ""
for i in range(strlen(utf8))
let encoded .= printf('%%%02X', char2nr(utf8[i]))
endfor
return encoded
endfunction
function! s:url_encode(str)
" RFC3986
return substitute(a:str, '[^a-zA-Z0-9_.~-]', '\=s:url_encode_char(submatch(0))', 'g')
endfunction
"}}}
"{{{ Twitter検索
function! SearchTwitter(...)
let queries = a:000
if a:0 == 0
let queries = [ input("Query: ", expand("<cword>")) ]
echo "\n"
endif
let query = s:url_encode( join(queries, ' ') )
let data = GetJson('http://search.twitter.com/search.json?locale=ja&q=' . l:query)
for tweet in data['results']
echohl WarningMsg
echon '@' . tweet['from_user']
echohl None
echon ': ' . tweet['text'] . "\n"
endfor
endfunction
" SearchTwitter: Twitter検索
command! SearchTwitter call SearchTwitter()
"}}}
"}}}
" vim: set foldmethod=marker:
@hayajo
Copy link
Author

hayajo commented Jul 13, 2012

資料はこちら。
Caoo - VimとJSON

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment