初心者でもわかるVim設定ファイルの読み方

エイチームライフスタイル アドベントカレンダー2017の11日目は、株式会社エイチームライフスタイルのWebエンジニア@matsu06が担当します。
今回は表題の通り、Vimの設定ファイルについて書いてみたいと思います。

# 対象者
- Vimの操作にようやく慣れてきたかなという方

# ゴール
- Web上にある偉大な先人たちのVim設定ファイルについて、なんとなく読めるようになる

# vimrcとは
Vimの設定はvimrcというファイルに記述して行いますが、このvimrcとは一体なにものでしょうか？
答えは、**Vimが起動時に自動的に実行するvim script**です。
設定をスクリプトで行うというとすごく難しそうですが、
新たにvim scriptをマスターする必要はなく、よく使うものは限られていますので、
今回はvimrcを記述する上でよく見かけるような気がする内容を説明させていただきます。

# オプション
まずvimrcで一番見かけるのがオプションになると思います。
オプションの中にはローカルな値を持てるものがあり、
それらのオプションは特定のバッファやウィンドウ内に限定されたオプション値を持つことができます。
オプションを設定するには `:setコマンド`を用い、ローカルなオプションを設定するには`:setlocal コマンド`を用います。
なお、どのようなオプションがあるかは`:help option-list`で確認できます。

```
setlocal number "行番号を表示するオプション
```

また、&を接頭辞にすることで、オプションを変数のように扱えます。

```
let &tabstop = 4 "タブ幅をスペース4つ分にする
```

## キーマッピング
キーマッピングには大きく分けてmapとnoremapがあり、

 - mapは再マッピングを行う
 - noremapは再マッピングを行わない

という違いがあります。
ぱっと見ただけだと使い分けが難しいと思いますが、いったんは

 - `他のキーマッピングでも使い回したいものはmapで定義`
 - `それ以外のものはnoremapで定義`

と考えるのが良いと思います。
また、キーマッピングはそれぞれのモードで独立して定義でき、どのモードのキーマッピングかは最初の文字で判別可能です。

|接頭辞|ノーマルモード|インサートモード|ビジュアルモード|
|:---:|:---:|:---:|:---:|
|なし|○|-|○|
|n|○|-|-|
|i|-|○|-|

上記の表の○となっている部分が定義されるモードになりますが、他にも多くのモード別のマッピングが存在します。

```
nnoremap + <C-a> "ノーマルモードの場合、+でインクリメントできるようにするできるようにする
nnoremap - <C-x> "ノーマルモードの場合、-でデクリメントできるようにするできるようにする
```

キーマッピングを確認したい場合は、以下のようなコマンドでそれぞれ確認できます。

```
"デフォルトのキーバインドの場合
:help index
"自分で設定したキーバインドの場合
:map " すべて確認
:imap " インサートモードだけ
:nmap " ノーマルモードだけ
```

なお、キーマッピングにはいくつかのオプションを使用することもできます。
代表的なものに`<silent>`があり、これは実行するコマンドがコマンドラインに表示されないようにするものです。

# 変数
設定ファイル内では変数が使用できますが、特に宣言は必要なく、次のように`letコマンド`を用いれば、その場で変数を作成できます。
なお、存在しない変数を使おうとするとエラーになります。

```
let hoge = 'fuga'
```

また、変数は接頭辞によってスコープが決定することができ、以下のようなものが存在します。

|接頭辞|スコープ|
|:---:|:---:|
|g:|グローバル|
|l:|ローカル|
|b:|バッファローカル|
|w:|ウインドウローカル|
|t:|タブローカル|
|s:|スクリプトローカル|
|v:|組み込み変数|

接頭辞を省略した場合のスコープは、組み込み変数に存在する場合は`v:`、関数内の場合は`l:`、それ以外の場合は`g:`という順番に適用されます。

変数を削除する場合は、`unlet `コマンドを用いると指定した変数を未定義にできますが、存在しないものを指定するとエラーになるので、その場合は`unlet!`コマンドを用います。

```
unlet! hogehoge "hogehogeという変数を削除（定義されていなくてもエラーにならない）
```

変数はさまざまなプラグインの設定や内部の制御に使用されています。
例えば、バージョン6以降のVimにはデフォルトでインストールされている*matchit.vim*も、設定ファイルに以下の記述をすることで、設定を追加できます。（*matchit.vim*の詳細はここでは説明いたしません。）

```
"matchit.vimの有効化（「%」で対応する括弧に移動するためのプラグイン）
runtime macros/matchit.vim
"対応ペアの追加(ifとendif間を「%」で移動できるようにする)
let b:match_words = "if:endif"
```

# 自動実行
特定のタイミングで特定のコマンドを実行するように設定するには、`autocmdコマンド`を使います。
便利ですが、複雑なコマンドなので、基本的な使い方のみ説明します。

```vim
"~/.vimrcを保存したとき、自動で再読込する
autocmd sample BufWritePost  ~/.vimrc  so ~/.vimrc
```

上記のような記述は、以下のような意味になっています。

 - *sample*はグループです。`augroupコマンド`により、一括指定することもできます。グループについては下記で詳細を説明します。
 - *BufWritePost*はイベントの種類で、今回のものはファイルの保存後を指します。なお、カンマ区切りで複数のものを同時に指定できます。どのようなイベントがあるかは、`:help {event}`で確認できます。
 - *~/.vimrc*の部分はパターンと呼ばれるもので、これに一致した場合のみ実行します。今回の場合はファイルの種類です。どういったパターンがあるかはイベントにより、パターンを使わないイベントもあるので、その場合は全てにマッチする`*`を指定します。
 -  *so ~/.vimrc*は自動実行するコマンドの部分で、複雑なことをする場合は関数を定義しておき、それを指定することもできます。

## グループについて
グループの設定は任意なのですが、autocmdを使用する際の注意する点として、
autocmdは上書きされずに実行された回数だけ定義されるというものがあります。
これを避けるため、autocmdはいったん削除してから再度定義するのが行儀が良いのですが、
その際、グループを指定し、削除することで想定していないautocmdを削除してしまうことを防ぐことができます。
削除するには`autocmd!`というコマンドを用います。

```vim
augroup sample
  autocmd! "読込時、sampleグループのautocmdを削除する
  autocmd FileType ruby setlocal number "削除対象
augroup END
autocmd sample FileType vim setlocal expandtab shiftwidth=2 "削除対象
augroup not_sample
  ... "sampleグループではないので、削除対象ではない
augroup END
```

# おわりに
いかがでしたでしょうか。
Vimはとっつきにくい部分が多いですが、使いこなせば生産性が爆発的に向上します。
これまでに挑戦し、挫折してしまった方も、これを機にVimに再チャレンジしてみてください！
なお、現在私がメインで使っているエディタはVisual Studio Codeです。。。

[エイチームライフスタイルアドベントカレンダー2017](https://qiita.com/advent-calendar/2017/ateam-lifestyle)、明日はVimキーバンドを使いこなすデザイナー @themeaningof8 さんがWebComponentsについて書いてくださるようです。お楽しみに！

[株式会社エイチームライフスタイル](http://life.a-tm.co.jp/)では、一緒に働けるチャレンジ精神旺盛な仲間を募集しています。興味を持たれた方はぜひエイチームグループ採用サイトを御覧ください。
http://www.a-tm.co.jp/recruit/