会社をずる休みして redmine のチケット一覧を表示する unite-yarm を作ってみた。
以前から pure vim で redmine のクライアントを書きたいと思っていたのだけど、力不足すぎて手が出せずにいた。チケットの一覧を取ってきて中身を表示するとこまでやったけど、xml 解析や文字列のエスケープ、さらに xml 生成がクソめんどくさくて放置。
そこに mattn さんの webapi-vim 登場。
webapi-vim: Vim Interface to Web API Description: Interface to WEB APIs. Currently this library support following protocols. * Basic HTTP * OAuth * Atompub * SOAP (in progress) This library include: XML Parser BASE64 Hash Algorism SHA1 Hash Algorism HMAC HASH Algorism
スゴイとしか言いようがない。自分も vim に限らず core なライブラリを書けるようになってみたいものだ。
試しに redmine の api を叩いてみる。
let res = http#get('http://localhost:3000/issues.xml') let xml = xml#parse(res.content)
2 行でゲット出来る!!(認証周りはまだ試してないのでスルー api acces key に対応)
(追記) と思ったら1行で行けるよ!
let xml = xml#parseURL(url)
各チケットに対しても簡単にアクセスできる(s:to_value は他では使ってほしくないけどちょっとだけ使いたい function として定義したんだけど、この場合どうしたらいいんだろう。あと、dictionary に詰め替えるのではなくオブジェクト指向っぽく属性の取得を a:xml に移譲したい)。
for dom in xml.childNodes('issue') call add(issues , s:to_issue(dom)) endfor function! s:to_issue(xml) " i want this to be inner function function! s:to_value(v) return empty(a:v) ? '' : a:v[0] endfunction let issue = { \ 'id' : s:to_value(a:xml.childNode('id').child) , \ 'project' : a:xml.childNode('project').attr['name'] , \ 'tracker' : a:xml.childNode('tracker').attr['name'] , \ 'status' : a:xml.childNode('status').attr['name'] , \ 'priority' : a:xml.childNode('priority').attr['name'] , \ 'author' : a:xml.childNode('author').attr['name'] , \ 'subject' : s:to_value(a:xml.childNode('subject').child) , \ 'description' : s:to_value(a:xml.childNode('description').child) , \ 'start_date' : s:to_value(a:xml.childNode('start_date').child) , \ 'due_date' : s:to_value(a:xml.childNode('due_date').child) , \ 'estimated_hours' : s:to_value(a:xml.childNode('estimated_hours').child) , \ 'done_ratio' : s:to_value(a:xml.childNode('done_ratio').child) , \ 'created_on' : s:to_value(a:xml.childNode('created_on').child) , \ 'updated_on' : s:to_value(a:xml.childNode('updated_on').child) , \} let issue.unite_word = '#' . issue.id . ' ' . issue.subject return issue endfunction
これに気を良くして、unite の source を作ってみた。
Unite redmine
チケットを選択すると
ここからどうするかはまだ考えていなくて、unite の何かしらの口を使って更新できたらいいなぁと思うけど。filetype (redmine) にイベントを設定して unite とは別に更新するのが現実的なのかな。
rubykaigi 2010 があった 3 ヶ月前に比べたら、ちょっとだけ vimscript を読み書きできるようになったけど未だに
- どう書いたら読みやすいのか
- モジュール?メソッド?script?分割はどうしたら分かりやすいのか
よく分からない。自分で書いておきながら頭に入りいくいのは作法が違うんだろうなぁと思う。
ちなみに、unite-yarm は yet another redmine の略で、本家が無いのに yet もクソもないけど、きっといいのが出てくるだろうということで unite-redmine は遠慮。
チケットのキャッシュ&破棄をどうするか、soruce に詰め替えたあとはどこまで残るのか(action実行後に破棄されるのか)、気になるところはいっぱい。