【Vim】Firestore Security Rules 用のプラグインを作った

表題の通り、作ってみました。VSCode 用やら Atom 用などはすでにあるのですが、Vim 用のが見つかんなかったので……。

* [delphinus/vim-firestore: A plugin for Firestore Security Rules.](https://github.com/delphinus/vim-firestore)

まずは、構文ハイライト機能を作りました。コード補完や定義ジャンプなどもそのうちできたらいいですね！（予定は未定）

<img width="520" alt="スクリーンショット 2019-02-10 19.53.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/8880/375b6e32-7638-a218-deca-8f4ac0e0b410.png">

こんな風に、いい感じに色がつきます。

# syntax プラグインの作り方

Vim の構文ハイライトはとにかく高機能です。ありとあらゆる言語のニーズに対応するため、機能は複雑で簡単に把握できるものではありません。もちろんドキュメントは完備されているのですが、現時点で **5,344 行 / 142,720 文字**あります。

* [syntax - Vim日本語ドキュメント](https://vim-jp.org/vimdoc-ja/syntax.html)

というわけで、かいつまんで要点だけ書きます。

## `ftdetect` プラグイン

まずは、開いたファイルに対してどの構文ハイライトを使うのか決めないといけません。このために使われるのが `ftdetect` プラグインです。プラグインのディレクトリに `ftdetect/firestore.vim` というファイルを作ります。

```vim:ftdetect/firestore.vim
autocmd BufNewFile,BufRead firestore.rules set filetype=firestore
```

これには多くの説明はいらないでしょう。詳しくは [:h ftdetect][], [:h :autocmd][] などを読んでみてください。

[:h ftdetect]: https://vim-jp.org/vimdoc-ja/filetype.html#ftdetect
[:h :autocmd]: https://vim-jp.org/vimdoc-ja/autocmd.html#:autocmd

## `syntax` プラグイン

ここからが本番です。`syntax/firestore.vim` というファイルを作成し、まずはおまじないを記入します。

```vim:syntax/firestore.vim
if exists('b:current_syntax')
  finish
endif

" ... ここにプラグイン本体を書く ...

let b:current_syntax = 'firestore'
```

同じファイルタイプのファイルを開いたときに、重複して読み込まれないようにしているのですね。

## 文字に色がつく仕組み

Vim による構文ハイライトは以下のようにして行われます。

1. `:syntax` コマンドで**構文グループ**を定義する。
2. `:highlight` コマンドで**構文グループ**に色をつける。

[**構文グループ**][:h group-name]とは、指定した規則に基づいて区分した同種のアイテムを指します。……まあこの説明じゃまずわかんないと思いますので例をあげましょう。

[:h group-name]: https://vim-jp.org/vimdoc-ja/syntax.html#group-name

## 構文グループの種類

### [キーワード](https://vim-jp.org/vimdoc-ja/syntax.html#:syn-keyword)

一番単純な構文グループです。指定した単語を色付けするときに使います。

```vim
syn keyword firestoreTodo TODO FIXME XXX BUG
```

> `syn` は `syntax` コマンドの省略形です。ここから先は慣例に則って省略形を使います。`highlight` コマンドの省略形は `hi` です。

この例では `TODO`, `FIXME`, `XXX`, `BUG` という単語たちに `firestoreTodo` という名前をつけています。これが構文グループです。

### [リージョン](https://vim-jp.org/vimdoc-ja/syntax.html#:syn-region)

```vim
syn region firestoreFunctionBlock start=/{/ end=/}/
```

これも何と無く分かりますね。`{` から始まって、`}` で終わる領域（**リージョン**）に `firestoreFunctionBlock` という名前をつけています。

### [マッチ](https://vim-jp.org/vimdoc-ja/syntax.html#:syn-match)

```vim
syn match firestoreComment +//.*+
```

これも簡単。正規表現を使って指定するパターンです。この例では `//...` のような部分はコメントだよ、ってことで `firestoreComment` と名付けているのです。

## 構文グループに色をつける

あとは色付け……なのですが、一つ一つの構文グループに直接色を指定することはまずありません。Vim にはカラースキームというものがありますので、個人の好みによってつけたい色が異なるはずだからです。

そこで、ハイライトの[**リンク**][:h :hi-link]という機能を使います。システムにデフォルトで定められた構文グループにリンクすることで、同種の色を使うことを Vim に教えてあげるのです。

[:h :hi-link]: https://vim-jp.org/vimdoc-ja/syntax.html#:hi-link

```vim
hi def link firestoreComment Comment
```

これにより、`firestoreComment` という構文グループは `Comment` と同じ色にしてね、ということを伝えています。これにより、カラースキームごとに違った色で表示されるはずです。

# さらなる深みへ……

はい！今日はここまで！ここまでの説明で、構文ハイライトの基本は抑えられています。vim-firestore を作るために調べたヘルプへのリンクを載せておきますので参考にしてください。

* [cluster][:h :syn-cluster]
* [nextgroup][:h :syn-nextgroup], [skipwhite][:h :syn-skipwhite], [skipnl][:h :syn-skipnl]
* [matchgroup][:h :syn-matchgroup]
* [contains][:h :syn-contains], [contained][:h :syn-contained], [containedin][:h :syn-containedin]
* [keepend][:h :syn-keepend]

[:h :syn-cluster]: https://vim-jp.org/vimdoc-ja/syntax.html#:syn-cluster
[:h :syn-nextgroup]: https://vim-jp.org/vimdoc-ja/syntax.html#:syn-nextgroup
[:h :syn-skipwhite]: https://vim-jp.org/vimdoc-ja/syntax.html#:syn-skipwhite
[:h :syn-skipnl]: https://vim-jp.org/vimdoc-ja/syntax.html#:syn-skipnl
[:h :syn-matchgroup]: https://vim-jp.org/vimdoc-ja/syntax.html#:syn-matchgroup
[:h :syn-contains]: https://vim-jp.org/vimdoc-ja/syntax.html#:syn-contains
[:h :syn-contained]: https://vim-jp.org/vimdoc-ja/syntax.html#:syn-contained
[:h :syn-containedin]: https://vim-jp.org/vimdoc-ja/syntax.html#:syn-containedin
[:h :syn-keepend]: https://vim-jp.org/vimdoc-ja/syntax.html#:syn-keepend

また、以下の記事には大変お世話になりました。もっと詳しく知りたい人は参照してください。

* [Vim の構文ハイライトでクリスマスツリー🎄を飾ってメリクリする - はやくプログラムになりたい](https://rhysd.hatenablog.com/entry/2018/12/23/235933)
  * 構文ハイライト全然わかんない……ってときに出会った記事。これで今回のプラグインを書く気になりました。
* [Vim のカラースキームが微妙に気に食わないときの対処法 - 反省はしても後悔はしない](http://cohama.hateblo.jp/entry/2013/08/11/020849)
  * `SyntaxInfo` コマンド超便利ですね！