NeoVim、そしてdein.vimへ

# neovim
新世代のVimその名も[neovim](https://neovim.io/)
今までVimからの移行が面倒で使っていなかったのですが、使ってみると高速でちょっと嬉しいような機能も盛りだくさんでした。
Vimとの相違点を踏まえて、手早く移行するための記事になれば幸いです。

## dein.vim
プラグインマネージャーです。
何やら[neobundle.vim](https://github.com/Shougo/neobundle.vim)はバグフィックスのみになるらしく、今後は[dein.vim](https://github.com/Shougo/dein.vim)を使って欲しいとのことでした。
こちらもめちゃくちゃ高速に動作します。

> VimmerはShougo氏に足向けて寝ちゃいけない

これ一番言われてきてますから（私だけ）

## Install

```bash
brew install neovim/neovim/neovim # mac
```

他のOSの方は[インストール方法](https://github.com/neovim/neovim/wiki/Installing-Neovim)をみてください。
neovimは[wiki](https://github.com/neovim/neovim/wiki)にいろんな情報があって良いですぞこれ

## Settings

```zsh:.zshrc
# 省略...

export XDG_CONFIG_HOME=$HOME/.config

# 省略...
```

neoVimはXDG configurationというのをサポートしていまして、そのHOME_PATHを決められます。
私はテキトーに`~/.config`にしましたが、これはお好みで変更してください。

また私は設定ファイルが増えすぎることを極端に嫌うので、Vimと共用しています。
実際は今までのVimの設定ファイルなどにシンボリックリンク貼れば良いです。

```
ln -snfv ${HOME}/.vim ${HOME}/.config/nvim/
ln -snfv ${HOME}/.vimrc ${HOME}/.config/nvim/init.vim
```

Vimとneovimで設定を分けたい場合は`${XDG_CONFIG_HOME}/nvim/init.vim`だけ作成すれば良いかと思います。

またターミナルのtrue colorを使用する場合は以下の設定を入れましょう。

```vim:.vimrc
" シンボリックリンクを使わない人は${XDG_CONFIG_HOME}/nvim/init.vim
"if has('nvim')
"  2016/05/11 neovim update. ignore NVIM_TUI_ENABLE_TRUE_COLOR
"  Vimのオプションのtermguicolorsに対応されました
"  let $NVIM_TUI_ENABLE_TRUE_COLOR=1
"endif
set termguicolors
```

これでneovimの設定は終わりです。
厳密に言うと

* if_ruby
* if_lua
* if_perl
* if_mzscheme
* if_tcl

がなくなっており、依存しているプラグインは動かなくなりますので別のプラグインを使用する必要があります。（これについては後述）
Vimとの違いは[vim_diff](https://neovim.io/doc/user/vim_diff.html)にまとめられていますので、慎重に移行したい方は目を通しておくと良いのではないでしょうか。

## Plugins Settings

どちらかというと`dein.vim`の方をメインに書きたかったので、ここからの方が長いです。
まずは設定を見てもらうのが良いでしょう。

```vim:.vimrc
" dein settings {{{
if &compatible
  set nocompatible
endif
" dein.vimのディレクトリ
let s:dein_dir = expand('~/.cache/dein')
let s:dein_repo_dir = s:dein_dir . '/repos/github.com/Shougo/dein.vim'

" なければgit clone
if !isdirectory(s:dein_repo_dir)
  execute '!git clone https://github.com/Shougo/dein.vim' s:dein_repo_dir
endif
execute 'set runtimepath^=' . s:dein_repo_dir

if dein#load_state(s:dein_dir)
  call dein#begin(s:dein_dir)

  " 管理するプラグインを記述したファイル
  let s:toml = '~/.dein.toml'
  let s:lazy_toml = '~/.dein_lazy.toml'
  call dein#load_toml(s:toml, {'lazy': 0})
  call dein#load_toml(s:lazy_toml, {'lazy': 1})

  call dein#end()
  call dein#save_state()
endif
" プラグインの追加・削除やtomlファイルの設定を変更した後は
" 適宜 call dein#update や call dein#clear_state を呼んでください。
" そもそもキャッシュしなくて良いならload_state/save_stateを呼ばないようにしてください。

" 2016.04.16 追記
" load_cache -> load_state
" save_cache -> save_state
" となり書き方が少し変わりました。
" 追記終わり

" vimprocだけは最初にインストールしてほしい
if dein#check_install(['vimproc'])
  call dein#install(['vimproc'])
endif
" その他インストールしていないものはこちらに入れる
if dein#check_install()
  call dein#install()
endif
" }}}
```

はい、プラグインはtoml形式で記述できるようになりました。

```toml:.dein.toml
[[plugins]]
repo = 'Shougo/dein.vim'

[[plugins]]
repo = 'Shougo/vimproc.vim'
build = 'make'

[[plugins]]
repo = 'Shougo/neosnippet-snippets'
```

基本的にはこの書き方になります。
遅延読み込みする方はこちらへ

```toml:.dein_lazy.toml
[[plugins]]
repo = 'Shougo/neomru.vim'
on_path = '.*'

[[plugins]]
repo = 'jiangmiao/auto-pairs'
on_i = 1

[[plugins]]
repo = 'Shougo/neoyank.vim'
on_path = '.*'
on_i = 1

[[plugins]]
repo = 'Shougo/neosnippet'
depends = ['neosnippet-snippets']
on_i = 1
on_ft = ['snippet']

[[plugins]]
repo = 'Shougo/neocomplete'
if = 'has("lua")'
on_i = 1

[[plugins]]
repo = 'Shougo/deoplete.nvim'
if = 'has("nvim")'
on_i = 1

[[plugins]]
repo = 'Shougo/unite.vim'
depends = 'neomru.vim'
```

`neobundle.vim`と同様にプラグインの読み込みタイミングには多くのオプションをつけることができます。

* `on_i` 1を指定すると、インサートモードに入った時に読み込まれます
* `on_ft` 指定したファイルタイプの時に読み込まれます
* `on_path` バッファ名が一致した時に読み込まれます。`.*`を指定すると何かのファイルを開いた時に読み込まれるので、filerなどのプラグインで使うと便利です
* `on_source` 記載されたプラグインが読み込まれた後に読み込まれます
* `on_cmd` コマンドが実行された時に読み込まれます。`['Unite', 'UniteResume']`のようなプラグインのコマンドを指定するかと思います
* `on_map` `on_cmd`のマッピング版で`['<Plug>(neosnippet_expand_or_jump)']`のように指定します
* `depends` プラグイン間で依存性がある場合に使います。**ここに記述しても自動的にインストールされるわけじゃない点は`neobundle.vim`とは少し挙動が違うので要注意の人もいるかもしれません**
* `if` `'has("nvim")` などのように書いて条件に一致した場合のみ読み込まれます

多分よく使うのはここら辺かと思います。
オプションは他にもあるので[dein-options](https://github.com/Shougo/dein.vim/blob/master/doc/dein.txt)で見るか`:help dein-options`を参照してください。

先ほど記述した通り、一部のプラグインはneovimでは動きません。
有名な`neocomplete`は`deoplete.nvim`に置き換えられます。
`if`オプションなどでうまいことVimと分けてみだくさい。

Pythonは3のみをサポートしています。
以下のコマンドでpythonを有効化してください。

```bash
pip install neovim
```

## dein.vim on_source

neobundleではプラグインが読み込まれた際に実行する挙動が書けました。

```vim
let s:hooks = neobundle#get("unite.vim")
function! s:bundle.hooks.on_source(bundle)
  let s:ignore_globs = ['**/node_modules/**', '**/vendor/bundle/**', '**/bower_components/**', '**/tmp/cache/**']
  call unite#custom#source('file_rec,file_rec/async', 'ignore_globs', s:ignore_globs)
endfunction
```

これは以下のように書き換えられます。

```toml:.toml_lazy.toml
[[plugins]]
repo = 'Shougo/unite.vim'
depends = 'neomru.vim'
hook_post_source = '''
  let ignore_globs = ['**/node_modules/**', '**/vendor/bundle/**', '**/bower_components/**', '**/tmp/cache/**']
  call unite#custom#source('file_rec,file_rec/async', 'ignore_globs', ignore_globs)"
'''
```

### 2016.04.16 追記
以前はdein#tapで記述していましたが、`hook_add`プラグイン追加後,`hook_source`プラグインがsourceされる前,`hook_post_source`プラグインがsourceされた後,`hook_post_update`プラグインが更新された後の４つのメソッドが追加されました。より短く記述可能になりました。

## 最後に
neovimとdein.vimとの出会いによって私のエディター生活はかなり高速になりました。
設定はそれほど時間がかからないと思うので使ってみてください。

P.S.
今まで使っていなかったけど`:Unite file_rec/async:!`が良すぎる、なぜ今まで気づかなかったのか...プロジェクト内のファイル一瞬で見つけられますやん。
あと`neoyank.vim`の`:Unite history/yank`も優秀すぎる。
Shougo氏、本当にありがとうございます。