読者です 読者をやめる 読者になる 読者になる

Vimmerのあなたの為に。最高のカレンダーcalendar.vimを作りました - Vimはアプリケーションプラットフォームの時代に

Vim

Vimでカレンダーといえば, mattnさんのcalendar.vimが有名でした.
mattn - calendar-vim
しかし, 私には以下の不満点がありました.

  • 現在のVim Scriptから見ると, Vim Scriptの基本的な要素(文字列と数字)しか使っていない. ぶっちゃけ, コードが読みにくいし拡張しにくい.
  • 日付の計算, 表示部の構成など, 様々な要素が一つのファイルに書かれていて, ごちゃごちゃになっている.
  • キーボード入力に対して, インタラクティブでない. 例えば, hを押した時に隣の日に移動しない.


自分でカレンダーを一から書いてみたくなったんです.
というわけで...

calendar.vim作りました

itchyny - calendar.vim
どうぞ使って下さい.
:Calendarコマンドでカレンダーが開きます.
スクリーンショットはこんな感じ.
https://raw.githubusercontent.com/wiki/itchyny/calendar.vim/image/image.png


Google Calendarのカレンダー, Google Taskのタスクをダウンロード, 編集したい時は, 次の設定を使って下さい.

let g:calendar_google_calendar = 1
let g:calendar_google_task = 1

:Calendarでカレンダーをスタートすると, 認証が始まります.

calendar.vimの特徴

次の機能を提供します.

calendar.vimの開発履歴

私のcalendar.vimの開発の原点は, thumbnail.vimにまで遡ります.
thimbnail.vimと言うのは, バッファーをサムネイルで選択できるプラグインです.
itchyny - thumbnail.vim
https://raw.githubusercontent.com/wiki/itchyny/thumbnail.vim/image/image.png
「この技術でカレンダー作れるよな...」
このプラグインを作っている時に, そう思ったんです.


その後, mattnさんのcalendar.vimと出会います.
mattn - calendar-vim
vim.orgでの番号が52番と, かなり歴史のあるプラグインですが, ソースコードのお行儀が悪くて, とても拡張できたものではありませんでした.
辞書もリストもなかった時代に書かれたから仕方ないんですけどね.
calendar-vimに大きなカレンダーを追加しました - プログラムモグモグ
少しだけPRを送らせて頂きましたが, このPRを送った時には, もう自分でカレンダー書こうと決めていました.
「h」を押しても左の日に動かないなんて, 私にとっては毎日使えるものではなかったのです.


カレンダーの制作は, 暦の勉強から始まります.
6月や7月はコードを書かずに調査していたと思います.
Julian day - Wikipedia, the free encyclopediaなどを知り, 日付の計算がうまくいくことを何度も確かめました.
大量にランダムテストを行いました.
Julian Dayの計算が正しいことを数学的に証明したりしました.


8月にモックアップを書きました.
恐らく数百行ワンファイルだったと思います.
勢いで書いたので, 複雑に絡み合ってしまいました.
リファクタリングが嫌になり, しばらく放置しました.


10月に入りlightline.vimも落ち着いてきた頃, 重い腰をあげて絡み合ったコードをほぐす作業にかかりました.
まずは, 日付の計算を切り離しました.
Vim Scriptでオブジェクト指向の真似事をできることが分かったのも, この頃です.
ユリウス暦, グレゴリオ暦, さらに各国のカレンダーを用意しました.
ユリウス暦からグレゴリオ暦に変わった日付って国によって違うんですよ.


11月は, UI部分を書いていきました.
リッチなインターフェースとはなんだろう.
そんなことを考え始めたのもこの頃です.
calendar.vimは, 基本的に毎回全画面再描画します.
それをやっても重いと感じないよう, 何度も何度もプロファイルを重ねて高速化を図りました. (:profile便利ですよ)


12月は, Google Calendarとのデータのやり取りの部分を書きました.
webとのやりとりには, webapi-vimのコードをかなり参考にさせて頂きました.
APIをcalendar.vimのインターフェースからスムーズに叩くことが出来るようになったのは, 12月23日のことでした.
年末はドキュメントを用意し, しばらく使っても大きなエラーが見当たらないことを確認し, 2014年1月5日にようやくリリースを行いました.
lightline.vimは2日ほどと, かなりスピーディーに開発しましたが, 今回は6か月にも及ぶ長丁場でようやくここまで漕ぎ着けました.
現在, calendar.vimのディレクトリで*.vimのファイルの行数の総計は10867行となっています.


ここで「Vimアプリケーション」という概念を作りたいと思います.
そのために, Vimプラグインを分類してみましょう.

Vimプラグインの分類

これまでに, Vimプラグインは, 様々な物がリリースされてきました.
それらを, 幾つかの分類に分けてみましょう.

colorscheme プラグイン

カラースキームですね. solarizedとかwombatとかが例になります.

syntax プラグイン

特定の言語に対して, 様々な機能を提供してくれるものです.
簡単に言うと, 名前に言語が入っているやつです.
vim-jsonとかsyntaxm4.vimなどが例になります.

編集補助プラグイン

任意の言語のファイルに対し, 編集の補助を行うプラグインです.
コメントのプラグインや, 補完のプラグインがこれになります.

特別バッファープラグイン

プラグインが特別なバッファーを使って, 情報を提供するものです.
vimfilerやTweetVim, gmail.vimがこれにあたります.

プラグイン拡張プラグイン

他のプラグインAPIを用いて, 拡張するプラグインです.
uniteのsourceなどがこれにあたります.

プラグイン補助プラグイン

他のプラグイン作成者がコーディングが楽になるよう, 基本的な機能を提供するプラグインです. 他のプラグインの補助を行います.
vital.vimやwebapi-vim, vimprocなどがこれにあたります.

Vimはアプリケーションプラットフォームの時代へ

さて, calendar.vimは上記の分類の中では, 特別バッファープラグインになります.
しかし, 更にリッチものを表す概念として, 新しい言葉を定義したいと思います.
calendar.vimはこれまでの特別バッファープラグインに比べて, よりリッチなインターフェースを提供しているという自負があります.


ここに「Vimアプリケーション」という言葉を定義します.
その条件は以下の五つです.

  • 特別バッファープラグインであること
  • バッファーは, プラグインの状態を表示するだけの場所であること
  • 表示部がリッチであること
  • コードが適切にファイル分けされており, 各ファイルの機能が重複していないこと
  • 他のプラグインに依存しないこと


一つずつ, 見ていきます.

特別バッファープラグインであること

Vimアプリケーションは, 特別バッファープラグインのサブセットです.
特別なバッファーを開いて, 様々な機能を提供することが条件です.
編集補助プラグインは, アプリケーションではありません.

バッファーは, プラグインの状態を表示するだけの場所であること

プラグインは, バッファーから状態を得てはいけません.
プラグインの状態を表示するだけです.
そのため, 基本的に, 常に全画面書き換えすることになります.

表示部がリッチであること

レイヤーを重ねたりすることは, リッチであることの最低条件だと思います.
また, 一年, 一か月, 時計のように, 様々なビューを切り替えられる事もリッチの条件だと思います.

コードが適切にファイル分けされており, 各ファイルの機能が重複していないこと

機能毎にファイルが分かれているということです.
少し主観的かもしれません.

他のプラグインに依存しないこと

Windowsアプリケーションを思い浮かべて下さい.
既存のものに依存する場合は, それをアプリケーションに同包するのが普通だと思います.
例えば, 圧縮解凍プラグインや, 音楽プレイヤーなどを考えると良いと思います.
(この意味で, vital.vimの仕組みはかなり良いソリューションと言えます)
(オンデマンドで取ってくるものもありますね, それでもいいです. きちんと管理できるなら)


私の作ったcalendar.vimは, 以上の五つの条件をおおよそ満たしており, Vimアプリケーションと言って良いでしょう.


これまでの特別バッファープラグインは, Vimのバッファーを書き換え可能なバッファーとして追記したり数行を消したりするだけでした.
Vimアプリケーションは, これまでの行単位を意識させるプラグインとは異なり, 新しいインターフェースを提供します.
CSSがblock要素をどんどん重ねるように, Vimアプリケーションは様々なインターフェースを重ねます.
Vimバッファーという貧弱なキャンバスの上で, Vim Scriptでレンダリングエンジンを構築するのです.
Vimアプリケーションによって, Vimライフはより楽しくなります.


リッチなインターフェースと引き換えに, 動作は必ず遅くなります.
だってカーソルを移動するたびに全画面を再描画しますから.
ですから, 例えばvimshellのように, 大量の行を裁かないといけないようなものは, 今の形のほうが良いでしょう.
カレンダーのように, 行が増えていかないものだからこそ, この設計ができたのだと思います.

そしてVimはアプリケーションプラットフォームの時代へ

これまでに私が見てきた特別バッファープラグインは, どれもあまり良いインターフェースを提供しているとは思いませんでした.
少なくとも, 十分にリッチなプラグインに出会ったことはありませんでした.
そんな中でcalendar.vimは, 今の私に実装できる, 最高のインターフェースを提供できたと思っています.
今後, Vimアプリケーションが増えていくことを願っています.

VaaP

Vim as an application platform.
Vimの更なる可能性へ
淀みないチャレンジを