Vimプラグイン開発の勉強を兼ねて、docker-composeのシンタックスハイライト対応させた件

皆さまはじめまして。[しくみ製作所](https://sikmi.com/)のvim大好き@tarumzuです。

この記事は[Docker Advent Calendar 2016](http://qiita.com/advent-calendar/2016/docker)の12日目がキャンセルされてしまったため、代わりに書いてます。
あとDockerカレンダーですがVimの内容多めです。。ｗ
何卒ご容赦下さいm(__)m


# 序章
最近、業務時間外は無為に過ごしてしまっていたのですが、ふとtwitterのタイムラインに@mattn_jpさんのこんなツイートが流れてきました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ジョブジェンジ is 何 / “Vimmerを3つのレベルに分類する” <a href="https://t.co/NSZbWg6dGA">https://t.co/NSZbWg6dGA</a></p>&mdash; おののいも夫 (@mattn_jp) <a href="https://twitter.com/mattn_jp/status/803511712066347008">2016年11月29日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

内容を見るとvimmerとしてのレベルが定義されていたのですが、結構いい加減な内容で皆さん言っているとおり１と２の落差が激しいですｗ
ただ、vimプラグインという単語を見たときにふと、そろそろ何か作ってみたいな～と思い、
軽率にもこんなつぶやきをしてしまいました。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">そろそろLv2目指して頑張るか <a href="https://t.co/Yt2N9DbYpT">https://t.co/Yt2N9DbYpT</a></p>&mdash; taru_mizu (@taru_mizu) <a href="https://twitter.com/taru_mizu/status/803566360265510912">2016年11月29日</a></blockquote>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>

ということで、有言実行をモットー（嘘）にしている@tarumzuは実際に作ってみることにしました。とは言え、一から作るのは敷居が高いため、誰かのプラグインにパッチを送るという形でまずはやってみます。

何をしようかと考えた結果、最近業務でDockerをよく触っているので、[ekalinin](https://github.com/ekalinin)さんの[Dockerfile.vim](https://github.com/ekalinin/Dockerfile.vim)（Dockerfileのシンタックスハイライト＆スニペット）をdocker-composeに対応させてみよう！ということで勉強をはじめました。

# 開発環境の構築
まずはVimプラグインの開発環境構築です。

Vimプラグインを開発する場合、他のプラグインを入れていると、それらが邪魔をして正しい動作確認が出来ずにバグのもとになります。なので開発のときだけ設定を無効にし、開発以外はプラグインを有効にしたい．．．

そんな環境を簡単に構築できる@b4b4r07さんの記事が参考になりました。（記事の内容はNeoBundleを使った場合の設定方法でしたがdein.vimでも多少修正すればいけます）
http://qiita.com/b4b4r07/items/b319ce2fd414b1d1d833

上記の方法で、`.development.vim`が置かれたディレクトリ配下ではvimプラグインが無効になり、ディレクトリ配下にあるプラグインだけが有効になります。便利ですね！


# docker-composeハイライト対応
さて、環境ができたのでようやく作業に入ります。[Dockerfile.vim](https://github.com/ekalinin/Dockerfile.vim)をforkしてまずはdocker-composeのキーワードを列挙。


```vim:docker-compose.vim
" Keywords
syn keyword dockercomposeKeywords build context dockerfile args cap_add cap_drop
syn keyword dockercomposeKeywords command cgroup_parent container_name devices depends_on
syn keyword dockercomposeKeywords dns dns_search tmpfs entrypoint env_file environment
syn keyword dockercomposeKeywords expose extends extends external_links extra_hosts
syn keyword dockercomposeKeywords group_add image isolation labels links logging log_driver
syn keyword dockercomposeKeywords log_opt net network_mode networks aliases
syn keyword dockercomposeKeywords ipv4_address ipv6_address link_local_ips pid ports
syn keyword dockercomposeKeywords security_opt stop_signal ulimits volumes volume_driver
syn keyword dockercomposeKeywords volumes_from cpu_shares cpu_quota cpuset domainname hostname
syn keyword dockercomposeKeywords ipc mac_address mem_limit memswap_limit oom_score_adj privileged
syn keyword dockercomposeKeywords read_only restart shm_size stdin_open tty user working_dir
"" Volume configuration reference
syn keyword dockercomposeKeywords driver driver_opts external labels
"" Network configuration reference
syn keyword dockercomposeKeywords driver driver_opts enable_ipv6 ipam internal labels external
"" Versioning
syn keyword dockercomposeKeywords version services
```
[tarumzu/Dockerfile.vim#L15-L31](https://github.com/tarumzu/Dockerfile.vim/blob/master/syntax/docker-compose.vim#L15-L31)
最近docker-composeはよく使ってはいたけどまだまだ知らないキーワードが沢山あって驚いた．．
まだまだ奥が深いな～
（今見ると重複しているキーワードもありますがそれはご愛嬌ということでｗ）

続いてこれらのキーワードをハイライトさせる。

```vim:docker-compose.vim

(中略)

" Highlighting
hi link dockercomposeKeywords  Keyword
```
[tarumzu/Dockerfile.vim#L60](https://github.com/tarumzu/Dockerfile.vim/blob/master/syntax/docker-compose.vim#L60)

以上。簡単ですね。もっと複雑な構文があるとこうは行きませんが。

# docker-composeスニペット対応
次にスニペットもちゃちゃっと書いちゃいましょう。

```vim:docker-compose.snippets
snippet ve
	version: ${1:2}
snippet volumes
	volumes:
		- ${1:value}
snippet volume_
	volume_driver: ${1:driver}
snippet volumes_
	volumes_from:
		- ${1:name}
snippet exter
	external: ${1:boolean}
snippet ser
	services:
		${1:name}
snippet bu
	build:
		${1:value}
snippet conte
	context: ${1:dir}
snippet com
	command: ${1:command}
snippet dep
	depends_on:
		${1:value}
snippet env
	environment:
		${1:name}: ${2:value}


(略)

```
[tarumzu/Dockerfile.vim/snippets/docker-compose.snippets](https://github.com/tarumzu/Dockerfile.vim/blob/master/snippets/docker-compose.snippets)



ここまでのコードを動作確認してみるとちゃんとシンタックスハイライトされています！Vim神ってる！マジ神ってる！！（神ってるって全然聞かないけどほんとに流行大賞なの．．．？？）
<img width="742" alt="スクリーンショット 2016-12-13 16.13.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/106116/38b55493-4b30-5651-dcbb-60d842de6c2f.png">


  |
  
  
動作テストが完了したらプルリク送ります。結果、無事マージされました！ekalininさんありがとう！！

<img width="782" alt="スクリーンショット 2016-12-13 16.11.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/106116/c936bbc7-2118-29fa-a855-f1741cc4fe7e.png">

# 最後に

プラグイン開発というと結構敷居が高そうに思えますが以外と簡単に出来ます。（題材が簡単すぎたのかもしれませんが。。）

DockerやVimをもっと便利に使うためにご参考になれば幸いです。
それでは皆さま、良きDocker＆Vimライフを！