Unityのコード編集にVimを使ってみた

# 初めに
[CYBIRDエンジニア Advent Calendar](http://qiita.com/advent-calendar/2017/cybird) 24日担当の@koki_yamada です。新卒でCYBIRDに入社して1年目のまだまだ半人前のエンジニアです。
23日は@ntrv さんの GoでZabbixを爆速にしたかった でした。
Go言語、人気ですよね。私もマスターしたいです。

さて、私は普段業務でUnityを使用しているのですが、標準で用意されているIDEのMonoDevelopが、私の環境では頻繁に落ちてします。
なので、スクリプト編集用の新しいエディタとしてNeovimを使った環境を構築することにしました。
今回はその時の導入記録を公開します。

# 環境構築
今回導入するもの

- [Neovim](https://github.com/neovim/neovim)
- [dein.vim](https://github.com/Shougo/dein.vim)
- [deoplete.nvim](https://github.com/Shougo/deoplete.nvim)
- [omnisharp-vim](https://github.com/OmniSharp/omnisharp-vim)

OSは macOS Sierra です。

## Neovimのインストール
Homebrewを使用してインストールします

```sh
$ brew install neovim
```

簡単ですね。

## dein.vimのインストール

プラグインの管理ツールとしてdein.vimを使用します。

このプラグインはVim界で有名な[Shougo](https://github.com/Shougo)さんが開発されています。
'Dark powered Vim/Neovim plugin manager' らしいです。かっこいい

readmeによるとインストールするディレクトリはどこでも良いようなので、今回は例として候補にある ~/.cache/dein にインストールしました。

```sh
$ curl https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh > installer.sh
$ sh ./installer.sh ~/.cache/dein
```

## dein.vimの設定

Neovimの設定ファイルはVimと違い ~/.config/nvim/init.vim に配置されており、ここにdein.vimの設定を追加します。
今回は後述するTOMLファイルを使用するために、[こちら](https://qiita.com/sugamondo/items/fcaf210ca86d65bcaca8#%E8%A8%AD%E5%AE%9A)の設定を参考にしました。

```vim:init.vim
if &compatible
  set nocompatible
endif
" dein.vimインストール時に指定したディレクトリをセット
let s:dein_dir = expand('~/.cache/dein')
" dein.vimの実体があるディレクトリをセット
let s:dein_repo_dir = s:dein_dir . '/repos/github.com/Shougo/dein.vim'
" dein.vimが存在していない場合はgithubからclone
if &runtimepath !~# '/dein.vim'
  if !isdirectory(s:dein_repo_dir)
    execute '!git clone https://github.com/Shougo/dein.vim' s:dein_repo_dir
  endif
  execute 'set runtimepath^=' . fnamemodify(s:dein_repo_dir, ':p')
endif
if dein#load_state(s:dein_dir)
  call dein#begin(s:dein_dir)
  " dein.toml, dein_layz.tomlファイルのディレクトリをセット
  let s:toml_dir = expand('~/.config/nvim')
  " 起動時に読み込むプラグイン群
  call dein#load_toml(s:toml_dir . '/dein.toml', {'lazy': 0})
  " 遅延読み込みしたいプラグイン群
  call dein#load_toml(s:toml_dir . '/dein_lazy.toml', {'lazy': 1})
  call dein#end()
  call dein#save_state()
endif
filetype plugin indent on
syntax enable
" If you want to install not installed plugins on startup.
if dein#check_install()
  call dein#install()
endif
```

## TOMLファイルを作成する

dein.vimでは管理するプラグインのリストをTOML形式の外部ファイルから取得することができます。
起動時にプラグインを読み込む場合は`dein.toml`、特定の条件で読み込む場合は`toml:dein_lazy.toml`にプラグインを追加します。
今回は上記の設定で指定したように ~/.config/nvim 配下にtomlファイルを配置します。

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

`repo`にはプラグインのGithubのリポジトリ名を指定します。

## deoplete.nvimのインストール

VimにIDEのような入力補完機能を追加してくれるプラグインです。
ちなみに、このプラグインもShougoさんが開発されています。

このプラグインはPython3が必須となるので先にインストールしておきます。

```sh
$ brew install python3
$ pip3 install neovim
```

init.vimに以下を追加してNeovimでPython3が使えるようにします。

```vim:init.vim
let g:python3_host_prog = '/usr/local/bin/python3'
```

一度Neovimを起動してPython3が有効になっているか確認。

```sh
$ nvim
```

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

1と表示されたらOK

dein_lazy.tomlに以下の項目を追加します。

```toml:dein_lazy.toml
[[plugins]]
repo = "Shougo/deoplete.nvim"
hook_source = "let g:deoplete#enable_at_startup = 1"
on_i = 1
```

`hook_source`はプラグインが読み込まれる直前に実行されます。
`on_i`にはvimのインサートモード時にプラグインを起動したい場合に1を指定します。

## omnisharp-vimのインストール
C#の補完機能を追加するプラグインです。

OmniSharpは補完候補を提供するサーバーを立て、エディタとサーバー間で通信を行うことで補完表示する仕組みとなっています。
このサーバーはC#で書かれているのでmonoが必要です。

omnisharp-vimの方はPython2が必要になりますのでインストールします。
方法はPython3の場合と同じです。

```sh
$ brew install python
$ pip2 install neovim 
```

```vim:init.vim
let g:python_host_prog = '/usr/local/bin/python2'
```

```sh
$ nvim
```

```
:echo has('python')
```

こちらも1と表示されたらOKです。


dein_lazy.tomlに以下の項目を追加します。

```toml:dein_lazy.toml
[[plugins]]
repo = "OmniSharp/omnisharp-vim"
on_ft = ["cs"]
build = "xbuild server/OmniSharp.sln"
```

`on_ft`にはプラグインを起動するファイルタイプを指定します。
今回はC#のソースコードファイルを開いた時に起動したいので、"cs"と指定しています。

サーバーをビルドする必要があるので、`build`にはビルドするコマンドを指定しています。

## OmniSharp用ソースをインストール

deopleteでOmniSharpの補完を表示するにはOmniSharp用のソースが必要になります。
deopleteとOmniSharpの橋渡しをしてくれるようなものです。

dein_lazy.tomlに以下の項目を追加します。

```toml:dein_lazy.toml
[[plugins]]
repo = "Robzz/deoplete-omnisharp"
on_source = ["deoplete.nvim"]

```

`on_source`は別のプラグインが読み込まれた時に一緒に読み込みたい時に指定します。
今回は、deoplete.nvimと同時に読み込むようにしました。

## NeoVim起動
最後にNeoVimを起動します。
起動と同時にdein.vimのインストール機能で先ほど指定したプラグインがインストールされます。

# 使い方

OmniSharpサーバーを起動します。
パラメータにUnityのソリューションファイルを指定します。

```sh
cd ~/.cache/dein/repos/github.com/OmniSharp/omnisharp-vim/server/OmniSharp/bin/Debug
mono OmniSharp.exe -s ~/nvim_test/nvim_test.sln
```

あとは、NeoVimでプロジェクト内の.csファイルを開くだけです。
コードを入力すると補完機能が働いてくれます。

# まとめ

使ってみた感想ですが、軽快に動作してくれます。
私の環境ではIDEを使っていると結構動作が重くなったりするのですが、そういったこともなく快適です。
Unityのライブラリも自動的に読み込んでくれるので、問題なく補完できました。

Unityを使用している方は是非、試してみてはどうでしょうか？

[CYBIRD エンジニア Advent Calendar](http://qiita.com/advent-calendar/2017/cybird) 明日は @daisuke-senmyouさんの 恋愛ゲームにおけるキャッシュ戦略 です!