NeoVimのカラースキームが思った色と違うときの解決方法



これはVimおよび、ターミナル初心者(ターミナルという名称が正しいのかもよく分かっていない)がNeoVimのカラースキームと戦った話を備忘録としてまとめたものである。

**結論を急ぐ人は以下の文章を飛ばして結論を見てください。**
[結論](#結論)

# 序章
何度かNeoVimなどの環境構築していたときに、どうも思ったカラースキームの色にならないということが多々あった。
<img width="450" alt="スクリーンショット 2020-01-13 0.41.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320986/c9623afa-428a-6e69-7970-bf4405d52e59.png">
こんな感じ。
これは```seagull```というカラースキームでPythonファイルを開いた様子。
vim colorsにあるサンプルだとこんな感じ。
<img width="450" alt="スクリーンショット 2020-01-13 0.43.55.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320986/9f7f1b7d-7a8a-56d0-5e63-ebbfd4178c4f.png">
ぜんぜん違う。
一体誰が思ってもない色を出してくるエディタでプログラミングしないといけないのか。

## 環境
- macOS mojave
- NeoVim (0.4.3)
- Terminal.app (2.9.5)
- iTerm2 (3.3.7)

# ターミナルが取り扱う色
どうやらターミナルのテーマによって捉えている色が違うらしい。
Blackと言いつつ#000000ではなく、#0b0e0dみたいな。
ちなみに#0b0e0dはこれである。私の目では#000000との違いが一切わからない。
<img width="20" src="https://www.colorhexa.com/0b0d0e.png">

Terminal.appのテーマをいじりながらneovimを起動していたら、ところどころ色が変わっていた。
なので、ターミナルで設定されている色を基準に色を使っているっぽい。
<img width="675" alt="スクリーンショット 2020-01-13 0.42.35.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320986/518f6b3f-0eec-054c-e3c6-9a123dce5bbe.png">
左:Terminal.appのテーマ```Basic```でneovimを起動し、カラースキーム```seagull```を対応させたもの
右:Terminal.appのテーマ```Homebrew```でneovimを起動し、カラースキーム```seagull```を対応させたもの
ほとんど変わりがないように見えるが、よく見るとカーソルの色が違う。背景の透明度はTerminal.appのテーマの影響。
# ターミナルが出力できる色
Tearminal.app>環境設定>プロファイル>詳細のところに```xterm-256color```とある。
なので256色は出せるのだろうと、素人目の予想を建てる。

[MacのTerminalとvimで256色の確認](http://adragoona.hatenablog.com/entry/2014/11/03/152539)
これを参考にしつつTerminal.appが出力できる色を調べていると、ちゃんと256色出せることが判明。しかし、先程の結果を見て分かる通り、256色出せたところでTerminal.appの色設定に影響されてしまう。

[ターミナル環境 (iTerm, vim, tmux) をフルカラーで使う](https://blog.nakanishy.com/truecolor-vim.html)
いろいろ調べているとこの記事にたどり着いた。最近のターミナルだと256色じゃ飽き足らず、24bitのフルカラーを表示する気でいる。なんて卑しいんだ。
このフルカラーを使う規格(?)をTrue Colorというらしい。名前からして色が正確に出力されそうだ。このページに確認するスクリプトまで載ってある。非常に助かった。

[TrueColor.md](https://gist.github.com/XVilka/8346728#now-supporting-truecolour)
True Colorに対応しているorしていないターミナルのリストが載っているページ。
ここを見ると、どうやらTerminal.appはTrue Colorに対応していないらしい。TrueToneとか載せる暇あるならTerminal.appにTrue Colorを載せてくれApple。

というわけで、Terminal.appを捨て、iTerm2をインストール。

# 7割正しくなった
iTerm2を起動し、早速NeoVimを起動。先程同様にカラースキーム```seagull```を適応させてみる。
<img width="450" alt="スクリーンショット 2020-01-13 0.52.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320986/75b1eff2-d672-236e-9976-de1ee5bb9fe5.png">
惜しい。Terminal.appのときよりも雰囲気は近くなった。しかし、まだサンプルの```seagull```には程遠い。

また調べていると、次の記事が見つかった。
[Vimでtermguicolorsをオンにしたらちょっとハマった話](https://qiita.com/foooomio/items/9f5a1948104f8f26d38a)
どうやらVimでTrueColorを使うときには```termguicolors```オプションを有効にすることで、端末上でもTrueColorが使えるらしい。
というわけで```set termguicolors```で有効にする。
<img width="450" alt="スクリーンショット 2020-01-13 1.10.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320986/1566c9ab-a562-352e-64d1-438d8c66025c.png">
若干は違うけども、98%くらい思っていた色が出た。これにて解決。

# 結論
~~ターミナルのカラースキームとvimのカラースキームを対応させる。当たり前だろうけど~~

1. 使っているターミナルがTrue Colorに対応しているか調べる。対応していないなら乗り換える。
1. NeoVimでTrue Colorを有効にする```set termguicolors```を実行する
2. True Colorに対応しているカラースキームを当てる。

# おまけ
更に調べてみると、どうやらVimの色を設定する際に色の指定の属性として、次のような指定方法があるとのこと。

|key|意味|
|:--|:--|
| term | 白黒端末での属性 |
| cterm | カラー端末での属性 |
| ctermfg | カラー端末での文字色 |
| ctermbg | カラー端末での背景色 |
| gui | GUI での属性 |
| font | GUI でのフォント |
| guifg | GUI での文字色 |
| guibg | GUI での背景色 |
| guisp | GUI での波線色 |
そしてこのオプションはこのような動作をするらしい。
> ```termguicolors``` をオンにして使用されるのは```guifg```と```guibg```だけで、特に書いてないですが、```gui```は使われません。
引用:[Vimでtermguicolorsをオンにしたらちょっとハマった話](https://qiita.com/foooomio/items/9f5a1948104f8f26d38a)

True Color対応のカラースキームの確認方法として、カラースキームのファイルに```guifg```と```guibg```が設定されているかを調べればいいんじゃないのかと思ったりした。