Vim Advent Calendar 96 日目の記事になります。
はじめに
先日、声で家電を操作できるガジェット Future Home Controller(FHC)を購入しました。
私も声で家電を操作したり室温からエアコン温度を自動調節したりするインフラを作っていたのですが、FHC は更に高機能な面もあり、イイトコどりのハイブリッドにするため飛びついてしまいました。さてさて、そんな FHC の大きな機能の一つとして Web API のサポートが挙げられます。
非常に多くの Web API が用意されていますが、今回はこの中から、登録されている音声認識ワード一覧を取得する recog/list と、音声認識ワードの文字列で各機能を呼び出しできる recog/firebystring を webapi-vim を利用して叩くことで、Unite.vim から 家電を操作できる unite source を作りました。Vim は暮らしの一部となりました!
デモ
片手ふさがってるので連打してますが、通常は絞り込みで使ってます。
インストール
NeoBundle を使用していれば、以下のように書けます。
通常版
NeoBundle 'mattn/webapi-vim' NeoBundle 'hecomi/unite-fhc'
遅延ロード版
NeoBundleLazy 'hecomi/unite-fhc', { \ 'depends' : ['mattn/webapi-vim'], \ 'autoload' : { \ 'unite_sources' : 'fhc', \ }, \ }
設定
" FHC の IP let g:fhc_ip = '192.168.0.11' " FHC の Web API key let g:fhc_apikey = 'webapi_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
コード
今回はじめて plugin を書いてみたのですが、webapi-vim の至れり尽せり感がすごいので、特に詰まるところもなく他の言語と同じように処理を書くことが出来ました。
scriptencoding utf-8 let g:fhc = {} function! g:fhc.get_json(kind, opt) let l:opt = '' for key in keys(a:opt) let l:opt .= '&'.key.'='.a:opt[key] endfor let l:fhc_url = 'http://'.g:fhc_ip.'/api/'.a:kind.'?webapi_apikey='.g:fhc_apikey.l:opt let l:res = webapi#http#get(l:fhc_url) if l:res.content == '' return {'result': 'error', 'code': 'xxx', 'message': 'network error'} endif let l:json = webapi#json#decode(l:res.content) return l:json endfunction function! g:fhc.check_err(json) if a:json.result != 'ok' echo a:json.code . ': ' . a:json.message return -1 endif return 0 endfunction function! g:fhc.get_list() let l:json = self.get_json('recong/list', {}) if self.check_err(l:json) != 0 return [] endif return l:json.list endfunction function! g:fhc.firebystring(str) let l:json = self.get_json('recong/firebystring', {'str': a:str}) if !self.check_err(l:json) != 0 return endif endfunction let s:source = { \ 'name' : 'fhc', \ 'description' : 'exec future home controller commands', \ } call unite#define_source(s:source) function! s:source.gather_candidates(args, context) let l:command = 'call g:fhc.firebystring("%s")' return map( \ g:fhc.get_list(), \ '{ \ "word" : v:val, \ "source" : "fhc", \ "kind" : "command", \ "action__command" : printf(l:command, v:val), \ }') endfunction function! unite#sources#fhc#define() return s:source endfunction
基本的には、
let l:res = webapi#http#get(l:fhc_url)
で、対象の URL から json を引っ張ってきて、
let l:json = webapi#json#decode(l:res.content)
で、json を辞書型にデコードしてくれて、
l:json.list
にアクセスすれば、機能一覧の配列がもらえるので、そのまま unite source に使用しているだけです。楽ちんですね。
おわりに
他の方にも使って頂きたいですが、Vim ユーザと FHC ユーザの積集合 = 1人(= 自分)疑惑ある...。
明日はおしょーさん(id:osyo-manga)です!果たして100日行くのか…。