Ubuntu 18.04でNeovimを利用する

## 環境
 - OS: Ubuntu 18.04 LTS
 - fish version 2.7.1

## 目標
 - Neovimを新しく利用できるようにします。
 - Neovim利用に必要なPython環境は、pyenvを用いて作成します。
 - 以下のプラグインを利用します。プラグイン管理にはdein.vimを利用します。<br/>
   これらを特に記載している理由は、これらの導入にハマったからですが、一旦全消ししてから再度以下の手順を進めた中では再発しなかったので、そのハマりっぷりは結局割愛しました。たぶんPython環境が汚れていたのだと思います。
    - denite.vim
    - deoplete.vim 
 - 設定ファイルはクラウド上に保存し、複数端末で利用できるようにします。


## Neovimインストール

公式資料は以下。
[Installing Neovim](https://github.com/neovim/neovim/wiki/Installing-Neovim)


### 準備
Neovim、および利用するプラグイン導入に必要なPythonモジュールをインストールします。


#### Pythonコンパイル用パッケージインストール
pythonコンパイル時に必要なパッケージをインストールします。
参照: [python.jp](https://www.python.jp/install/ubuntu/index.html)

```
> sudo apt update
> sudo apt install build-essential libbz2-dev libdb-dev \
  libreadline-dev libffi-dev libgdbm-dev liblzma-dev \
  libncursesw5-dev libsqlite3-dev libssl-dev \
  zlib1g-dev uuid-dev tk-dev
```


#### pyenv 環境構築
[pyenv](https://github.com/pyenv/pyenv)をgit cloneで取得します。

```
> git clone https://github.com/pyenv/pyenv.git ~/.pyenv
```

取得したpyenvへのパス追加と、pyenvのinit処理を、fish設定に記述します。

```~/.config/fish/config.fish
set PYENV_ROOT ~/.pyenv/bin
set -x PATH $PYENV_ROOT $PATH
status --is-interactive; and pyenv init - | source
```

installerシェルを実行します。
これを行わなくても、`pyenv --version`は動きますが、`pyenv install --list`などが動きません。
参考情報: [pyenvでインストールを実行しようとしたら"no such command 'install' "となる](https://qiita.com/Soh1121/items/68f231d759a76de8c471)

```
> sudo ~/.pyenv/plugins/python-build/install.sh
```


設定反映＆確認。

```
> source ~/.config/fish/config.fish
> echo $PYENV_ROOT
/home/<USER>/.pyenv/bin
> which pyenv
/home/<USER>/.pyenv/bin/pyenv
> pyenv --version
pyenv 1.2.9-2-g6309aaf2
> pyenv install --list | grep 3.7.2
3.7.2
```


#### Neovim用Python環境構築
ここまででpyenvの設定は完了しました。
つづいてPythonの導入をしていきます。

```
> pyenv install 3.7.2
> pyenv rehash
> pyenv global 3.7.2
> pyenv version
3.7.2 (set by /home/<USER>/.pyenv/bin/version)
> python --version
Python 3.7.2
> pip --version
pip 18.1 from /home/<USER>/.pyenv/bin/versions/3.7.2/lib/python3.7/site-packages/pyp (python 3.7)
```

Neovim導入に際しては、Pythonのneovimモジュールが必要です。

```
> pip install neovim
> pip freeze | grep neovim
neovim==0.3.1
```


#### Neovim設定時に使用するXDG系変数の定義

config.fishに追記します。

```~/.config/fish/config.fish
set -x XDG_CONFIG_HOME $HOME/.config
set -x XDG_CACHE_HOME $HOME/.cache
```

確認

```
> source ~/.config/fish/config.fish
> echo $XDG_CONFIG_HOME
/home/<USER>/.config
> echo $XDG_CACHE_HOME
/home/<USER>/.cache
```


### インストール
Neovimのインストールには、以下コマンドを実行します。

```
sudo add-apt-repository ppa:neovim-ppa/stable
sudo apt-get update
sudo apt-get install neovim
```

`add-apt-repository`が利用できない場合は、以下コマンドで取得しましょう。

```
sudo apt-get install software-properties-common
```

確認しましょう。

```
> which nvim
/usr/bin/nvim
> nvim --version
NVIM v0.3.1
Build type: Release
 : 以下ずらずらっと情報が表示されます。
```

起動してみます。

```
> nvim
```

Neovim内で以下のコマンドを実行し、Python3が正しく認識されていることを確認しましょう。
返却値が`1`であればOKです。`0`の場合、Pythonのnvimモジュールが正しくインストールされていない等の問題があります。


```
:echo has('python3')
1
```


## 設定

### init.vim作成

Neovimでは.vimrcの代わりに、init.vimを設定ファイルとして利用します。
以下、`$XDG_CONFIG_HOME`に設定情報を作成しましょう。

```
> echo $XDG_CONFIG_HOME
/home/<USER>/.config
> mkdir $XDG_CONFIG_HOME/nvim
> touch $XDG_CONFIG_HOME/nvim/init.vim
```


既存の.vimrcをそのまま使う場合は、init.vim内で.vimrcを読み込めます。
この手順は`:h nvim-from-vim`で確認できます。
今回はクリーンインストールするので、init.vimはゼロから作っていきます。


### dein.vimの導入

プラグインマネージャーとしてdein.vimを利用します。

init.vimを用いてdein.vimのインストールをします。
プラグインリスト`dein.toml`は`nvim/dein/toml`以下で管理し、プラグインは`$XDG_CACHE_HOME`に入れる構成です。
この記事では簡略化のため、遅延ロードは行いません。
まずはdein.tomlを作成しましょう。

```
> mkdir -p $XDG_CONFIG_HOME/nvim/dein/toml
> touch $XDG_CONFIG_HOME/nvim/dein/toml/dein.toml
```

続いてinit.vimを編集します。

```~/.config/nvim/init.vim
" dein.vim {{{
"  directory configuration
let s:config_home = empty($XDG_CONFIG_HOME) ? expand('~/.config') : $XDG_CONFIG_HOME
let s:dein_config_dir = s:config_home . '/nvim/dein'
let s:toml_file = s:dein_config_dir . '/toml/dein.toml'
let s:cache_home = empty($XDG_CACHE_HOME) ? expand('~/.cache') : $XDG_CACHE_HOME
let s:dein_dir = s:cache_home . '/dein'
let s:dein_repo_dir = s:dein_dir . '/repos/github.com/Shougo/dein.vim'
"  dein installation
if !isdirectory(s:dein_repo_dir)
  call system('git clone https://github.com/Shougo/dein.vim ' . shellescape(s:dein_repo_dir))
endif
"  path
let &runtimepath = s:dein_repo_dir . "," . &runtimepath
if dein#load_state(s:dein_dir)
  call dein#begin(s:dein_dir)
  call dein#load_toml(s:toml_file, {'lazy': 0})
  call dein#end()
  call dein#save_state()
endif
"  install new plugins
if has('vim_starting') && dein#check_install()
  call dein#install()
endif
" dein.vim }}}
```

init.vimへの追記後、Neovimを再起動しましょう。
`$XDG_CACHE_HOME/dein`以下に、dein.vimが取得されます。
この手順ではdein.vimのヘルプが読めるようになりませんでしたので、再起動後に、dein.vimのヘルプタグ生成をしておきます。
dein.vimのヘルプが確認できればOKです。

```
:helptags ~/.cache/dein/repos/github.com/Shougo/dein.vim/doc
:h dein
```

※dein.vim自体のインストール確認を単独でどのように行うべきか、良い方法があればご教示いただけると嬉しいです。
ここでは次項でプラグインをdein.vimでインストールすることで代替確認としています。


では、dein動作確認も兼ねて、プラグインを導入してみます。
軽量で細かい設定が不要な、itchyny氏のステータスラインプラグイン「[lightline.vim](https://github.com/itchyny/lightline.vim)」を導入してみましょう。
dein.tomlを編集し、Neovimを再起動しましょう。

```~/.config/nvim/dein/toml/dein.toml
[[plugins]]
repo = 'itchyny/lightline.vim'
```

以下のように、Neovim起動時に未取得のプラグインがインストールされます。
ステータスラインの表示は変わりましたか？

```
> nvim
[dein] Not installed plugins: ['lightline.vim']
[dein] Update started: (yyyy/mm/dd hh:MM:ss)[dein] Updated plugins:
[dein]   lightline.vim(1 change)
[dein] Done: (yyyy/mm/dd hh:MM:ss)Press ENTER or type command to continue
```

これで各設定ファイルの疎通確認が取れました。
あとはinit.vimおよびdein.tomlを好きに編集するだけです。

### 特定プラグインのインストール
denite.nvimおよびdeoplete.nvimをインストールしていきます。
denite.nvim等の一部プラグインでは、モジュール取得後にNeovim上で`:UpdateRemotePlugins`を実行する必要があります。

```dein.toml
[[plugins]]
repo = 'Shougo/denite.nvim'
```

さきほどの手順の中で、init.vimを編集して、起動時に不足プラグインをインストールするようにしています。
モジュール取得には、いったんNeovimを再起動するのが楽でしょう。
再起動後に`：UpdateRemotePlugins`を発行し、またNeovimを再起動します。

Denite.nvimが正しく利用できるかどうかを確認するため、以下のコマンドを試しに発行してみます。
バッファ一覧が表示されれば成功です。Escキーを押すと元の画面に戻ります。

```
:Denite buffer
```

ではここから、deoplete.nvimを導入します。

```dein.toml
[[plugins]]
repo = "Shougo/deoplete.nvim"
```

```init.nvim
let g:deoplete#enable_at_startup=1
```

例によってNeovimを再起動します。
試しに何かbufferに、入力済の文字列などを入力してみましょう。
補完候補は表示されましたでしょうか？



## alias設定(Vimの置き換え)

既存のVimをNeovimに置き換えるため、aliasを設定します。
`vim`でNeovimを呼び出せるようにしましょう。
一応、`ovim`でVimも使えるようにしておきます。

```
> alias vim "/usr/bin/nvim"
> alias ovim "/usr/bin/vim"
> funcsave vim ovim
> ls ~/.config/fish/functions | grep vim
ovim.fish
vim.fish
```


## 設定ファイルのクラウド移行

設定ファイルをクラウド上のリポジトリに置くことで、複数端末での設定共有が容易になります。
そこからダウンロードし、該当フォルダにシンボリックリンクを張ると設定完了です。

設定、展開はこのような感じです。
Dropboxなどでも良いと思いますが、私はgithubを利用しています。

```
> mv ~/.config/nvim ~/.config/nvim_bkp
> git clone https://github.com/giwanaga/dotfiles ~/dotfiles
> ln -sf ~/dotfiles/nvim ~/.config/nvim
```

## その他
一部のVim設定はNeovimでは利用できません。
.vimrcを引き続き利用する場合には、Vimの場合にのみその設定を読むように分岐させるほうが健全です。

```~/.vimrc
if !has('nvim')
  set clipboard+=autoselect
endif
```


## 結び
.vimrc整理をしていて、いっそNeovimに変えるか、という考えがよぎったのが移行の出発点でした。
逆に言うと確たる目的は特にありませんでした。まあ男は度胸、なんでも試してみるもんですよね。
Neovim導入案内の記事は多いですが、だいたいmac用とかzsh前提とかだったので、どなたかのお役に立てればと重複をおそれずに今回まとめてみた次第です。

ちなみに以下が私の設定ファイルです。何かのご参考かマサカリの的にでもなれば。
ただし本記事執筆時点の状態は保証されません。
https://github.com/giwanaga/dotfiles/tree/master/nvim/