女子受けバツグン必殺Vimカラースキームを自作しよう

# 【前置き】カノジョを作る作戦を立てよう
今年もカノジョができなかった @yamasy1549 です :innocent: 

さてエンジニアという職業ですが、一般の方々に印象を聞くと「ずっとPCに向かってる」「話しかけづらい」「黒い画面に吸い込まれそう」と言われ[要出典]、実際黙々とコードを書くだけだと人間関係が希薄になりやすいです[要出典]。関わる人間の数が圧倒的に少ないのではカノジョができなくても仕方ないし、そんな中でカノジョを作ろうと思ったらもう狙いの精度を上げるしかありません。今回は「それとなく自分の趣味を明らかにし、同じ趣味の人に気づいてもらう」ことで精度向上を図る作戦を考えましょう。

## 作戦
おもむろにVimを立ち上げます。

カノジョできてるエンジニアとカノジョできないエンジニアの何が違うのか、それは普段使っているエディタに表れているに違いない、と思い簡単な調査をしました。

![image](https://qiita-image-store.s3.amazonaws.com/0/54805/2a7d5cc2-94bc-c3e3-cd98-56950ed87ded.png)![image](https://qiita-image-store.s3.amazonaws.com/0/54805/12186fa0-560f-a8dd-8cee-1f0295cf314d.png)

僕がVimユーザーなのでVimに絞って聞いてみましたが、2つの結果は大して変わりませんでした。
しかしこれは有用な結果です。みんな似たようなものを使っているなら、ここで自分の個性をアピールすればきっと誰かが自分の存在に気づいてくれるはずです。

前置きが長かったですが、自分の趣味をアピールできるようなVimカラースキームを作っていきましょう。

# 【本題】Vimカラースキームを作ろう
## 構成を知ろう
一から書くのはしんどいので、既存のカラースキームを上書きしていくのがラクで良いです。

今回は [iceberg](https://github.com/cocopon/iceberg.vim) というカラースキームを参考にしました。

### 諸々の設定

```vim
set background=dark
set background=light
```
カラースキームの背景を設定します。
icebergのようにどちらかの色使いのみ対応するなら、カラースキーム側にどちらかを書いておきます。両対応にするなら、カラースキーム側でdark向けの色使いとlight向けの色使いを振り分けることができます（例 :  [solarized](https://github.com/altercation/solarized/blob/master/vim-colors-solarized/colors/solarized.vim#L379)）。

```vim
if exists("syntax_on")
  syntax reset
endif

hi clear
" or
highlight clear
```
すべてのハイライト設定を一旦クリアします。

### Highlight command

```
:help highlight
```
で詳細を確認できます。


```vim
highlight {group-name} {key}={arg}
```
よく使うのが上の形です。

#### group-name
```
:help group-name
```
で詳細を確認できます。

`{group-name}` として以下が使えます。

|  | group-name | 意味 | 例 |
| --- | --- | --- | --- |
| * | `Comment` | コメント |  |
|  | `Constant` | 定数 |  |
|  | `String` | `""` で囲まれるような文字列定数 | `"this is a string"` |
|  | `Character` | `''` で囲まれるような一文字の定数 | `'c'` `'\n'` |
|  | `Number` | 数字定数 | `234` `0xff` |
|  | `Boolean` | ブール定数 | `TRUE` `false` |
|  | `Float` | 浮動小数点定数 | `2.3e10` |
| * | `Identifier` | 識別子 |  |
|  | `Function` | 関数名（クラスメソッドなども） |  |
| * | `Statement` | 命令文 |  |
|  | `Conditional` | 条件 | `if` `then` `else` `endif` `switch` |
|  | `Repeat` | 繰り返し | `for` `do` `while` |
|  | `Label` | ラベル | `case` `default` |
|  | `Operator` | 演算子 | `sizeof` `+` `*` |
|  | `Keyword` | その他のキーワード |  |
|  | `Exception` | 例外 | `try` `catch` `throw` |
| * | `PreProc` | 一般的なプリプロセッサ |  |
|  | `Include` |  | `#include` |
|  | `Define` |  | `#define` |
|  | `Macro` | `Define` と同じ |  |
|  | `PreCondit` |  | `#if` `#else` `#endif` |
| * | `Type` |  | `int` `long` `char` |
|  | StorageClass |  | `static` `register` `volatile` |
|  | `Structure` |  | `struct` `union` `enum` |
|  | `Typedef` | `typedef` 宣言 |  |
| * | `Special` | 特殊なシンボル |  |
|  | `SpecialChar` | 特殊な文字定数 |  |
|  | `Tag` | `CTRL-]` で宣言元にジャンプできる |  |
|  | `Delimiter` | 注意が必要な文字 |  |
|  | `SpecialComment` | コメント内での特記事項 |  |
|  | `Debug` | デバッグ命令 |  |
| * | `Underlined` | 目立つ文、HTMLリンク |  |
| * | `Ignore` | 空白、見えない |  |
| * | `Error` | エラーなど間違った構造 |  |
| * | `Todo` | 特別注意の必要なもの | `TODO FIXME and XXX` |

`*` マークの付いているものは親、付いていないものは子として扱われます。
例えば

```vim
highlight Comment ctermfg=15

" CUIでの Comment group の文字色を灰色(15)にする
```

とすると、`Constant` `String` `Character` `Number` `Boolean` `Boolean` も自動的に灰色になります。

#### highlight-groups
```
:help highlight-groups
```
で詳細を確認できます。

`{group-name}` として以下が使えます。

| group-name | 意味 | 例 |
| --- | --- | --- |
| `ColorColumn` | `set colorcolumn` で設定された場所の文字 | [行のn文字目以降に色を付ける](http://blog.remora.cx/2013/06/source-in-80-columns.html) |
| `Conceal` | 代替テキスト | [長い文字を短い文字で置き換えて表示する](http://blog.remora.cx/2011/02/use-vim-conceal.html) |
| `Cursor` | カーソルのある文字 |  |
| `CursorIM` | IMEモードでの `Cursor` |  |
| `CursorColumn` | `set cursorcolumn` されているときのカーソルのある文字の桁（縦方向） |  |
| `CursorLine` | `set cursorline` されているときのカーソルのある文字の行（横方向） |  |
| `Directory` | ディレクトリ名・特別な名前 |  |
| `DiffAdd` | 差分モードでの追加された行 |  |
| `DiffChange` | 差分モードでの変更された行 |  |
| `DiffDelete` | 差分モードでの削除された行 |  |
| `DiffText` | 差分モードでの変更されたテキスト |  |
| `EndOfBuffer` | バッファ中で最終行以降の残りのスペースを埋める行 | ['~' を無効にする](http://secret-garden.hatenablog.com/entry/2016/08/16/000149) |
| `ErrorMsg` | コマンドライン上でのエラーメッセージ |  |
| `VertSplit` | ウィンドウを垂直分割したときの区切り行 |  |
| `Folded` | 折りたたまれた行 |  |
| `FoldColumn` | 折りたたみがあることを表示する列 |  |
| `SignColumn` | sign（目印）を表示する列 |  |
| `IncSearch` | `insearch` のハイライト |  |
| `LineNr` | `:number` `:#` コマンドの行番号 |  |
| `CursorLineNr` | `set cursorline` か `set relativenumber` されているときの現在行の行番号 |  |
| `MatchParen` | カーソル下（または直後）の括弧とそれに対応する括弧 |  |
| `ModeMsg` | `showmode` のメッセージ |  |
| `MoreMsg` | more-prompt のメッセージ |  |
| `NonText` | ウィンドウ端の `@` や `showbrake` で設定されたような、実際のテキストには存在しない文字 |  |
| `Normal` | 普通のテキスト |  |
| `Pmenu` | ポップアップメニューでの普通の項目 |  |
| `PmenuSel` | ポップアップメニューでの選択された項目 |  |
| `PmenuSbar` | ポップアップメニューでのスクロールバー |  |
| `PmenuThumb` | ポップアップメニューでのスクロールバーのツマミ |  |
| `Question` | hit-enter プロンプトと yes/no |  |
| `Search` | 最後に検索した単語のハイライト |  |
| `SpecialKey` | メタキーなど |  |
| `SpellBad` | スペルチェッカーに認識されない単語 |  |
| `SpellCap` | 大文字で始まるべき単語 |  |
| `SpellLocal` | スペルチェッカーが他の地域で使われると認識する単語 |  |
| `SpellRare` | スペルチェッカーによって殆ど使われないと認識される単語 |  |
| `StatusLine` | カレントウィンドウのステータスライン |  |
| `StatusLineNC` | カレントウィンドウでないウィンドウのステータスライン |  |
| `TabLine` | タブページ行のアクティブでないページのラベル |  |
| `TabLineFill` |  タブページ行のラベルがないところ|  |
| `TabLineSel` | タブページ行のアクティブなページのラベル |  |
| `Title` | `:set all` `autocmd` などの出力タイトル |  |
| `Visual` | ビジュアルモード選択 |  |
| `VisualNOS` | "Not Owning the Selection" のときのビジュアルモード選択 |  |
| `WarningMsg` | 警告 |  |
| `WildMenu` | `windmenu` の補完での現在の候補 |  |

#### highlight-args
```
:help highlight-args
```
で詳細を確認できます。

カラー端末用には `cterm*={arg}` 、そうでない端末用には `term*={arg}`、gVimなど用には `gui={arg}` を使います。

| {key}={arg} | 意味 | args |
| --- | --- | --- |
| `cterm={arg}` | 文字のスタイル | `bold` `underline` `undercurl` `reverse` `inverse` `italic` `standout` `NONE` |
| `ctermbg={arg}` | 文字の背景色 | 色番号 |
| `ctermfg={arg}` | 文字の色 | 色番号 |

`cterm*={arg}` では16進数での色指定ができないので、色番号で指定する必要があります。
参考 : [ターミナルで使える色と色番号を一覧にする](http://qiita.com/tmd45/items/226e7c380453809bc62a)

## 書いてみよう
上で紹介したものは設定のほんの一部ですが、数カ所色を変えるだけでも見た目がかなり変わります。

[矢澤にこ](http://www.lovelive-anime.jp/otonokizaka/member/member09.html)さんを見ながら作るとこうなる

![image](https://qiita-image-store.s3.amazonaws.com/0/54805/e0256f95-6a08-3d99-fdd2-5831fa69662a.png)

[絢瀬絵里](http://www.lovelive-anime.jp/otonokizaka/member/member02.html)さんを見ながら作るとこうなる

![image](https://qiita-image-store.s3.amazonaws.com/0/54805/34cc95db-e7f2-06e2-d5af-f2b0491fad3e.png)

Vim上で

```
:so $VIMRUNTIME/syntax/hitest.vim
```
と叩いてしばらく待つと、どのエイリアスがどの色を表示しているかを確認できるので便利です。

## もっとできること
- 色番号の変数管理
- `dark` `light` での色使いの振り分け
    - https://github.com/w0ng/vim-hybrid/blob/master/colors/hybrid.vim#L99
- `gui` `cterm` 両対応
    - https://github.com/w0ng/vim-hybrid/blob/master/colors/hybrid.vim#L85
- などなど…

# まとめ
僕の例はかなり下手ですが、こんな感じで自分の好きなキャラの色をベースにカラースキームを作るといつか誰かに「◯◯さんのエディタってエリチ仕様ですよね！」って気づいてもらえ…たらいいんじゃないかなぁ…

来年は「カノジョできてるエンジニア Advent Calendar」のほうでお会いできるようお祈りしています :pray: Enjoy Vim life!

# 参考
- Vimカラースキームの作り方
    - [Vim の Color Scheme を自作するためのあれこれ](http://nishikawasasaki.hatenablog.com/entry/20111222/1324547769)
    - [カラースキームを作ってみよう](http://thinca.hatenablog.com/entry/20130410/1365530054)
    - [vimのcolorscheme](http://d.hatena.ne.jp/yuta84q/20090319/1237471714)
    - [vimrcのcolorグループ一覧](http://tech.alters.co.jp/vimrc/vimrc%E3%81%AEcolor%E3%82%B0%E3%83%AB%E3%83%BC%E3%83%97%E4%B8%80%E8%A6%A7/)
- 既存のカラースキーム
    - [iceberg](http://cocopon.github.io/iceberg.vim/)
    - [vim-colors-japanesque](https://github.com/aereal/vim-colors-japanesque)
    - [vim-hybrid](https://github.com/w0ng/vim-hybrid)
- Vim
    - [Vim でバッファ外のチルダ("~") の表示を無効にする](http://secret-garden.hatenablog.com/entry/2016/08/16/000149)
    - [【VIM】新機能“CONCEAL”構文属性を使う](http://blog.remora.cx/2011/02/use-vim-conceal.html)
    - [【VIM】80桁教信者の憂鬱](http://blog.remora.cx/2013/06/source-in-80-columns.html)
- その他
    - [ラブライブ！](http://www.lovelive-anime.jp/otonokizaka/)
    - [ターミナルで使える色と色番号を一覧にする](http://qiita.com/tmd45/items/226e7c380453809bc62a)

僕のお気に入りのカラースキームはhybridです。