Vim/GVim => Neovim/Neovim-qt 移行時にやったこと

[以前書いた記事](https://qiita.com/s4kr4/items/78b197ab8d2491c1f012)で紹介したVim設定ファイル群を`Neovim`に対応させたので、変更点を書いていきます。

# XDG Base Directory Specification

Neovimの設定ファイルは`XDG Base Directory Specification`という仕様に拠っています。
詳しい仕様は[この辺り](https://wiki.archlinux.jp/index.php/XDG_Base_Directory_サポート#XDG_Base_Directory_Specification)が参考になると思います。

簡単に言うと、設定ファイルは`~/.config`以下、ユーザ固有のキャッシュファイル等は`~/.local/cache`以下に配置するなど、各アプリケーション関係のファイルを統一的に管理しやすくするのが目的の仕様です。
Neovimの設定ファイルは`~/.config/nvim/init.vim`に配置するのが慣例となっていて、この仕様に従っているといえます。


## ファイル構成

Neovim移行にあたって、従来のVimの設定を全て`~/.vimrc`に書いていたような人は、ほとんどそのまま`~/.config/nvim/init.vim`にコピペで済みます。

しかし僕は以前の記事に書いたように、設定をいろいろ分割して管理していたので、そのままコピペすると外部ファイルを読み込めなかったりして、一筋縄ではいきませんでした。

対応策として、設定ファイルを置くPATHをVim環境変数に設定し、外部ファイルを読み込む箇所でそれを使用する形にしました。

また、VimとNeovimを共存させるため、起点の設定自体は従来通り`~/.vimrc`に書き、`~/.config/nvim/init.vim`へSymlinkを貼りました。
以前`~/.vim`に配置していたファイル群は、XDG仕様に従って`~/.config/vim`に移動しました。
フォルダ構造自体は変わっていません。

![vim.png](https://qiita-image-store.s3.amazonaws.com/0/29000/c6a7fbb1-803a-1bde-d86a-3c0bdea58dc3.png)


## ~/.config/nvim/init.vim

```vim:~/.config/nvim/init.vim(~/.vimrc)
let $XDG_VIM_HOME = $HOME.'/.config/vim'

set runtimepath+=$XDG_VIM_HOME
set runtimepath+=$XDG_VIM_HOME/after

runtime! init/*.vim
runtime! functions.vim
```


1行目で設定ファイルのPATHを環境変数`XDG_VIM_HOME`に設定しています。
以降、外部のファイルを読み込むときは必ずこの環境変数を使います。

下行でこれを使ってruntimepathを追加しています。


## dein.vim の設定

`dein.vim`自体のダウンロードとプラグインのインストール処理を`vim/init/10_dein.vim`に書いています。
インストールするプラグインのリストは`dein.toml`と`dein_lazy.toml`に外出ししているので、`vim/init/10_dein.vim`からこれらのファイルを読み込んでいます。
このときの読み込み先指定を`$XDG_VIM_HOME`で書き換えました。

```diff:vim/init/10_dein.vim
  ...

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

-   let s:toml      = expand($HOME.'/.vim/dein.toml')
-   let s:lazy_toml = expand($HOME.'/.vim/dein_lazy.toml')
+   let s:toml      = expand($XDG_VIM_HOME.'/dein.toml')
+   let s:lazy_toml = expand($XDG_VIM_HOME.'/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

  ...
```


## プラグイン設定ファイル読み込み

`dein.vim`で読み込むプラグインの設定は、`dein.toml`や`dein_lazy.toml`に埋め込むこともできますが、
僕は別に設定ファイルを作り、それを読み込む方法をとっています。
`vim/plugins/*.vim`がその設定ファイルです。
この設定ファイルを`dein.toml`と`dein_lazy.toml`から読み込むときのPATH指定を書き換えました。

```diff:vim/dein.toml
  ...

  [[plugins]]
  repo = 'osyo-manga/vim-over'
- hook_add = 'source $HOME/.vim/plugins/vim-over.vim'
+ hook_add = 'source $XDG_VIM_HOME/plugins/vim-over.vim'

  [[plugins]]
  repo = 'tyru/caw.vim'
- hook_add = 'source $HOME/.vim/plugins/caw.vim'
+ hook_add = 'source $XDG_VIM_HOME/plugins/caw.vim'

  [[plugins]]
  repo = 'thinca/vim-splash'
- hook_add = 'source $HOME/.vim/plugins/vim-splash.vim'
+ hook_add = 'source $XDG_VIM_HOME/plugins/vim-splash.vim'

  ...
```


# Vim/Neovimでのプラグインの切り分け

どちらか一方でしか使わないプラグインはもう片方では読み込みたくないので、`dein.vim`の機能である`on_if`オプション + `has`関数を使って切り分けました。

```:dein_lazy.toml
...

[[plugins]]
repo = 'Shougo/deoplete.nvim'
on_i = 1
on_if = 'has("nvim")'
hook_source = 'source $XDG_VIM_HOME/plugins/deoplete.vim'

[[plugins]]
repo = 'Shougo/neocomplete.vim'
on_i = 1
on_if = '!has("nvim")'
hook_source = 'source $XDG_VIM_HOME/plugins/neocomplete.vim'

...
```

# オプションの切り分け

クリップボード連携など、Vim/Neovimで設定方法が違うオプションもあったりします。
こちらもプラグインと同様に、`has`関数で分岐させました。

```vim:vim/init/20_general.vim
...

if has('nvim')
    set clipboard=unnamedplus
else
    set clipboard=unnamed,autoselect
endif

...
```

---

PATH問題で少し詰まりましたが、Vimとほぼ同様の設定をNeovimでも動かせるようになりました。
もちろんVimも今までどおりきちんと動作しています。