vimのカラースキームの設定・編集方法（初心者〜上級者）

# 背景

このあいだ勉強会の一環で **vim・Neovimのカラースキームについて** 紹介したので，それをこちらでも記事として残そうと思います．
自分はカラースキームを探したり，環境にあった色にチューニングしたりが好きです．そこで，そういったことをしている中で培って来た知識を「カラースキームってなに？」という人から，「カラースキームを編集したい」という人まで，広く浅く紹介したいと思います．

他にも[cocoponさんの記事](https://cocopon.me/blog/2017/12/inside-vimconf-presentation/)なども非常に勉強になると思います．

# 前提条件

vimの環境によっては異なるカラースキームや設定方法がある可能性があります．
今回はvimとNeovimを使用した場合の２種類で紹介しますが，もし他の設定方法がある場合にはコメント等よろしくお願いいたします）

Neovim: `NVIM v0.3.4`

勉強会の際に作成したスライド： 


# はじめに

カラースキームに凝ること，2年．vimの戦闘力はvimrcの行数という説があります．
ある意味面白い例えだと思ったので，自分もカラースキームの戦闘力的何かがあれば面白いと思い考えました．

その結果，
![colorscheme_level.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234222/027bb4b4-35ac-6873-adf7-a4fe05e9d1ef.png)

というレベル分けで紹介することにしました （他の分け方もあるかと思いますが笑）
今回も，この５段階と分けて紹介をしようと思います！

# カラースキームとは

カラースキームとは，簡単に紹介すると

> vimの色の付け方を指定するもの

です．
しかし，カラースキーム好きとしてさらに踏み込むと，
> vimを開きたくなるもの

ですね．

下の図を見ていただくとわかると思いますが，カラースキームの有無で大きく**「見やすや・かっこよさ」**が異なることがわかると思います．

![vim_colorscheme_diff.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234222/a8077309-15c7-2bf1-e59e-414b5398c750.png)

では，実際にカラースキームの設定や編集方法に移りたいと思います．

# 設定方法

## Level 1 - デフォルトのカラースキームを使用

**デフォルトってなんだ？** と思われる方もいらっしゃるかと思います．
実は，vimはインストールした時点でいくつかのカラースキームが一緒にインストールされます．

自分のmacのvimの場合，下記の18種類が入ってました！（ほとんど使ったことがない...)
（`/usr/share/vim/vim80/colors`内に存在しました．）

```
blue.vim
darkblue.vim
default.vim
delek.vim
desert.vim
elflord.vim
evening.vim
industry.vim
koehler.vim
morning.vim
murphy.vim
pablo.vim
peachpuff.vim
ron.vim
shine.vim
slate.vim
torte.vim
zellner.vim
```
レベル１ではこの辺を設定するところから始めたいと思います．

## 一時的に反映

### `:colorscheme` コマンドについて

カラースキームの設定方法の前に，いくつか便利なコマンドを紹介したいと思います．

まず，vimの画面上でどんな感じになるか確認したいと思われる方もいらっしゃるかと思います．
**vimはそれができます！**

vimの画面上で
`:colorscheme[space][tab]`
と打つとコマンドライン上にpc内に入っているカラースキームのリストが表示されます．

<img width="1187" alt="Screenshot 2019-04-17 at 14.27.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234222/12a2a286-a631-5ad0-8c97-ae89138fe050.png">

この状態で， `矢印キー`で左右に動き，見たいカラースキームの上で `Enter`を押すと，そのカラースキームが反映されます．

しかし，これは`一時的な反映` であり，再度vimを開くと，元のカラースキームに戻ってしまいます．

## 全体に反映

全体に反映するには `.vimrc` 内に記述します．

### `.vimrc` とは

`.vimrc`とは：

> vimの設定を記述する**専用ファイル** 

です．簡単な設定から，パッケージについて等，全てこのファイルに記述します．（正確には他のファイルでも良いのですが，このファイルに最後に `source`  をしないと，反映されません）

ちなみに豆知識で， `.~rc` 系の設定ファイルをよく見かけるので，`rc`ってなんなんだろうと調べたところ，初期のUNIXの遺産のようで `run commands` の略ではないかという説があるらしいです．

### `.vimrc` どこにあるんだ

自分が初めてvimを触りだしたところ， `.vimrc`を見つけられず，苦労をしました．（サイトによって，記述場所が異なっていたり，Neovimだったので，vimとは違って大変でした...)

そこで，簡単に今のvimがどの設定ファイルを読み込んでいるのか見つけられるコマンドがあります．

それがこちら！

```vim

:echo $MYVIMRC
```
こうすることによって，

```shell

$ HOME/.vim/.vimrc 
or
$ HOME/.config/nvim/inti.vim 
```

となります．上記が`vim`の場合で下記が`nvim`の場合です．

**※ neovimの.vimrcは`init.vim`というファイルです**

### あとは`.vimrc`に記述するだけ！

`.vimrc` の場所がわかれば，あとはそこに記述するだけです．
書き方は非常にシンプルで

```vim

syntax enable
colorscheme [colorscheme name]
```

とするだけです．

## Level 2 - 公開されたカラースキームを使用

公開されたカラースキームとは
> GithubやBitbucketなどのOP上で公開されたカラースキームのこと

と定義しました．
多くの人がこういった，**公開されたカラースキーム**を使用するのではないかと思います．

使用方法として**２種類**あります．
1. 自分のpc上にダウンロードして使用
2. パッケージを使用してインポートして使用

よく見かける王道のカラースキームは下記のようなものがあげられると思います．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234222/092971f2-527c-4b06-bbfe-d26b41bbeedc.png)

では，実際に[molokai](https://github.com/tomasr/molokai)を例に設定する方法を紹介したいと思います．

### 1. 自分のpc上にダウンロードして使用

デフォルトのカラースキームは`colors/`というディレクトリ内に存在しました．
そこと同じディレクトリに入れる方法もありますが，一般的には下記のようなディレクトリ構造を作成し，その中に入れます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234222/3a2a44d1-d96d-a98e-8af2-54c53b268586.png)

<FONT COLOR=red>**注意:**</FONT> 初期状態では存在しない場合，`mkdir`等で作成してください．

あとは，そこにmolokaiのカラースキームファイルをダウンロードするだけです．

githubからcloneして，`./colors/molokai.vim`というファイルを先ほど作成した`./colors`内に移動するだけです．

あとは上記のデフォルトのカラースキームを使用した時と同様のことを`.vimrc`内に記述するだけです．

```vimscript
syntax enable
colorscheme molokai
```

### 2. パッケージを使用してインポートして使用

「自分のpc上にダウンロードして使用」でも良いのですが，新しいカラースキームを取り込みたい時に，いちいちダウンロードして，移動して，と行なっているのは面倒臭いです．

そこで`dein`というパッケージを使用して簡単に取り込む方法を紹介したいと思います．
そちらのインストール方法などは，また別の話になるので割愛させていただきますが，以下の記事がインストール方法などを紹介しているので是非，使っていない人は試してみてください！

1. [NeoBundle から dein.vim に乗り換えたら爆速だった話](https://qiita.com/delphinus/items/00ff2c0ba972c6e41542)
2. [NeoVim、そしてdein.vimへ](https://qiita.com/okamos/items/2259d5c770d51b88d75b)

(オススメのパッケージに関するスライドは[こちら](https://www.slideshare.net/ShunIwase/vim-141450302))

実はこの`dein`を使用すると２行だけで終わってしまいます．
ディレクトリを作成する必要もないです．

```vimscript

call dein#add('tomasr/molokai')
colorscheme molokai
```

これで全体に反映されてしまいます．

以上がレベル2の紹介です！

では，実際に編集の方に入っていきます．

# 編集方法

カラースキームを追求していくうちに，編集したくなる欲求が出てくきます（来ない人ももちろんいます）

そこで，実際どう編集するのか，そしてそのための便利ツールを紹介したいと思います．

## 事前知識

### ターミナルについて

vimを使用していると，２種類のterminalに出会います．
1つ目が`cterm`，そして2つ目が`GUI`です． これらの大きな違いは色の数です．

ctermは**256色**しか色がないターミナルです．macのデフォルトはこちらになります． また，色のパレットは`Xterm colors`というのを使用しています．
GUIは名前の通り，グラフィックに適応しているので**hex**で色分けがされています．

基本的に，公開されているカラースキームはどちらのターミナルにも対応しているので，中身を見ると

```vimscript

hi Operator guifg=#af0000 guibg=NONE guisp=NONE gui=bold ctermfg=124 ctermbg=NONE cterm=bold
```

のように，書かれています．それは以下のような意味があります．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234222/96b418a0-e238-69f3-9f2a-1fa01296dfce.png)

ctermのターミナルの色を変える場合， `ctermbg / ctermfg`  を変更し， GUIのターミナルの色を変えたい場合は `guibg / guifg` を変更します．

### ハイライトグループについて

カラースキームはハイライトグループごとに色が振り分けられています．これらのシンタックスグループは言語をvimに登録する際に決められており，例えば下記のようなものがあります．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234222/b24f22d1-a198-8ab6-bda9-6ca3b66e27a5.png)

なので，一概に「この色を変えたい！」と言っても，他の要素が影響を受ける場合もあるので十分に注意してから変えたほうがいいです．

### ANSIIの設定

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234222/cb804d86-9361-3969-6623-313d0a61c60b.png)


## レベル3: 公開されたカラースキームをカスタマイズして使用

では，これらの知識をもとに色を編集する方法を紹介します．

### 便利コマンド・ツール

その前に，編集を行う際の便利コマンド・ツールについてです．

### 現在のカラースキームをグループごとの色を知る方法
今のカラースキームが全体的にどのような色分けになっているのか知る方法として以下のコマンドがあります．

```
:highlight
もしくは省略して
:hi
```
とvimのコマンドライン上で打つと下記のような画面が表示されます．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234222/13fe08ca-16f9-1ec6-f9d9-093875b3e0ca.png)

これらは右から
`ハイライトグループ 表示例 色`
です．

#### Xterm Color Table
いちいちXtermの色を調べるのは面倒臭い上に，現在のターミナルでどのような色になるのか知りたい場合，[こちら](https://github.com/guns/xterm-color-table.vim)のプラグインが役に立ちます．

gitの`README.md`にも記述されているのですが，このプラグインを`.vimrc`に記述するだけで， `:XtermColorTable`というコマンドが使用できるようになります．

実際，下記のようになります．

![image.png](https://camo.githubusercontent.com/e2aee8ab7e70f75f9f0d7ca2d4d920bc5c4d7cc8/687474703a2f2f67756e732e6769746875622e636f6d2f787465726d2d636f6c6f722d7461626c652e76696d2f696d616765732f787465726d2d636f6c6f722d7461626c652e706e67)
https://github.com/guns/xterm-color-table.vimのREADME.mdから引用

#### シンタックのグループ名を知れる関数

色を帰る際に非常に困るのが，変えたいところのハイライトグループがわからない！ということです．
そこで，[cohama様のこちら](http://cohama.hateblo.jp/entry/2013/08/11/020849)の記事に書かれている関数が**非常に**便利だったので紹介したいと思います．

```vimscript
function! s:get_syn_id(transparent)
  let synid = synID(line("."), col("."), 1)
  if a:transparent
    return synIDtrans(synid)
  else
    return synid
  endif
endfunction
function! s:get_syn_attr(synid)
  let name = synIDattr(a:synid, "name")
  let ctermfg = synIDattr(a:synid, "fg", "cterm")
  let ctermbg = synIDattr(a:synid, "bg", "cterm")
  let guifg = synIDattr(a:synid, "fg", "gui")
  let guibg = synIDattr(a:synid, "bg", "gui")
  return {
        \ "name": name,
        \ "ctermfg": ctermfg,
        \ "ctermbg": ctermbg,
        \ "guifg": guifg,
        \ "guibg": guibg}
endfunction
function! s:get_syn_info()
  let baseSyn = s:get_syn_attr(s:get_syn_id(0))
  echo "name: " . baseSyn.name .
        \ " ctermfg: " . baseSyn.ctermfg .
        \ " ctermbg: " . baseSyn.ctermbg .
        \ " guifg: " . baseSyn.guifg .
        \ " guibg: " . baseSyn.guibg
  let linkedSyn = s:get_syn_attr(s:get_syn_id(1))
  echo "link to"
  echo "name: " . linkedSyn.name .
        \ " ctermfg: " . linkedSyn.ctermfg .
        \ " ctermbg: " . linkedSyn.ctermbg .
        \ " guifg: " . linkedSyn.guifg .
        \ " guibg: " . linkedSyn.guibg
endfunction
command! SyntaxInfo call s:get_syn_info()
```
これを`.vimrc`内に記述すると，`:SyntaxInfo`というコマンドが使用可能になり，実際にカーソルの下にあるコードのハイライトグループがわかります！`link to`のリンク先まで知れるのはありがたいです．

表示例：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234222/c433da07-d8f9-ebc6-14d8-0ac55e864b49.png)


以上，編集においての便利コマンド・ツールとなります．

### 一時的に編集をしてみる

実際に全体に反映させる前に，どのようになるのか一時的に編集させる方法があります．

それが先ほども紹介した`highlight / hi`コマンドです．
例えば，行番号の背景色を変えたいとした時，赤がどのような感じになるか確認します．

この時，赤をhexの`#ff0000`とした時，xterm256では`1`に該当します [^1] ．

```
:highlight LineNr ctermbg=1 guibg=#ff0000
もしくは
:hi LineNr ctermbg=1 guibg=#ff0000
```
ここで行なった編集は，現在のvimの画面にしか反映がされません．
なので，気に入ったものは`.vimrc`やカラースキームをダウンロードして直接編集しましょう．

### 全体に反映

#### .vimrcに記述する方法

感覚で，もし色を変えるのなら，下記のようにカラースキームを設定した後に変えたい箇所の色を上書きすればいいのでは？と思われるかもしれません．

```vim
colorscheme foo-bar

highlight LineNr ctermbg=1 guibg=#ff0000
```

しかし，上記には穴があり，正しい書き方があるらしいです．

その理由を説明しているのが[こちら](https://gist.github.com/romainl/379904f91fa40533175dfaec4c833f2f)です．
英語＋長いので要点だけ取り出すと，以下のことが問題となります．
>  But you like to try new colorschemes, or you prefer to have different colorschemes for different filetypes or time of the day and your overrides don't carry over when you change your colorscheme.

なので，カラースキームをインポートする前に下記のように記述しましょう．

```vim
autocmd ColorScheme * highlight LineNr ctermbg=1 guibg=#ff0000

colorscheme foo-bar
```

#### 直接カラースキームファイルに記述する場合

この場合はカラースキームファイルをクローンしてきて，変えたいところを探し，置き換えるだけです．
ただ，この場合，もしgitに載せたりする場合は`著作権`などに気をつけるべきですね．

以上でレベル3の編集については終わりです．

# レベル4: 自作カラースキームを使用

ここまできたら，実際に作ってみようと思われた方もいらっしゃるかと思います．
しかし，実際に作るとなると，色々大変なことが多いです．

[thincaさんの記事](https://thinca.hatenablog.com/entry/20130410/1365530054)や[cocoponさんのIcebergを作成した際の記事](https://cocopon.me/blog/2016/02/iceberg/)が自作する際に読んでおきたい記事です！

私はデザイナではないので，デザインに関することは言えないのですが，その代わり作成する際に非常に役に立ったおすすめサイト・ツールなどを紹介したいと思います．　

## 手順

下記は，いろんな人のカラースキームを拝見した際に行なっていると思われる手順です．

![create_my_own.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234222/2b440e0e-1136-805e-9b71-d57d4b39ef97.png)

## オンライン編集ツール

[Vivifyというこちらの](http://bytefluent.com/vivify/index.php)編集ツールが非常に役に立ちます．

## テストコード
[Rosetta Code Dataのこちら](https://github.com/acmeism/RosettaCodeData)のレポジトリには数多くの言語で書かれたコードがあります．

## .vimrcに記述

`~/.vim/colors`もしくは`~/.config/nvim/colors`内にファイルを置くと，`.vimrc`で設定することができます．
書き方は上記のデフォルトや公開されたカラースキームと同様です．

# レベル５: 自作カラースキームを公開し使用する方法

あまり，レベル４と差異はないのですが，`公開する`というところが重要だと思い別のレベルにしました．

Githubに公開する方法は非常に単純で，ディレクトリ構造などを間違えなければすぐできます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234222/a419a804-5567-3a60-44b2-65b4f5d959ee.png)

パッケージ等で読み込むのは`./colors`内のトップのファイルのみなので，そこだけ注意が必要そうですね．

# 最後に
本当に広く浅くで紹介しました．
もし間違っている箇所などございましたら，コメントよろしくお願いいたします．

# 参照サイト

How to set and use a vim color scheme: 
https://alvinalexander.com/linux/vi-vim-editor-color-scheme-colorscheme
molokaiのカラースキーム：
https://github.com/tomasr/molokai
Vim のカラースキームが微妙に気に食わないときの対処法:
http://cohama.hateblo.jp/entry/2013/08/11/020849

[^1]: terminalによっては，ANSIIのパレットの色によって少し異なる色が出力される可能性があります． `:XtermColorTable`などでxterm256の色合いを調べつつ，もっとも求めているものに近い色を探してください．