WindowsでUnityのコーディングをgvimで行う(OmniSharp-Vim)

[OmniSharp-Vim](https://github.com/OmniSharp/omnisharp-vim)を使えばVimでUnity(C#)のコーディングを行うときもインテリセンス機能を使えます

今までは[Visual Studio Code](https://code.visualstudio.com/)でコードを書いていたが，Unityと同時起動していると時々重く感じることがあったのでVimへの以降を試してみました．
以下のサイトを参考にしたのですが，いずれのページもそのままでは動かなかったので自分が導入できた時に行った変更点などを記します

# 参考ページ
* [Vim で C# を書くなら OmniSharp で決まり！ - 永遠に未完成](https://thinca.hatenablog.com/entry/20130522/1369234427)
* [VimでUnity C#のコーディングをするための設定 - Yucchiy's blog
](http://blog.yucchiy.com/2016/05/05/unity-vim-omnisharp/)
* [gvimでOmniSharpを使おうとすると“'omnifunc' は設定されていません”と出る - stack overflow](https://ja.stackoverflow.com/questions/5855/gvim%E3%81%A7omnisharp%E3%82%92%E4%BD%BF%E3%81%8A%E3%81%86%E3%81%A8%E3%81%99%E3%82%8B%E3%81%A8omnifunc-%E3%81%AF%E8%A8%AD%E5%AE%9A%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%9B%E3%82%93%E3%81%A8%E5%87%BA%E3%82%8B)
* [windows vim 開発環境構築メモ(gvim + neobundle) - Qiita](https://qiita.com/hikachan/items/a189f3051dd94f551cc9)
* [Omnisharp導入でハマったところ - 踊るプログラマー](http://waken.hatenablog.com/entry/2016/03/03/213256)

# 使用環境
* Windows 10 Pro
* [vim80-kaoriya-win64](https://www.kaoriya.net/software/vim/) に同梱しているgvim.exe
* Unity2017.3.0f3
* [Python2.7.15](https://www.python.org/downloads/windows/)(64ビット版)

# VimにPythonを導入する
デフォルトの状態では，Vim起動後に `:echo has('python')` と入力すると`0`が表示されました(Pythonが使用できない状態)
[Pythonのダウンロードページ](https://www.python.org/downloads/windows/)からPython2.7.15をインストールし，Python27ディレクトリの中にあった`Python27.dll`をVimと同じディレクトリに置きます．
再度Vimを起動し，`:echo has('python')`を入力すると，`1`が返されるようになりました．

# NeoBundleのインストール
自分はLinux環境やWSLでは既にdein.vimを使用していますが，OmniSharp-Vimをインストール時にビルドするなどはっきりと分かっていない部分があったので一旦参考記事に従いNeoBundleを使用しました．
Windowsに[Git](https://gitforwindows.org/)をインストールし，[windows vim 開発環境構築メモ(gvim + neobundle) - Qiita](https://qiita.com/hikachan/items/a189f3051dd94f551cc9)に従いNeoBundleを導入しました．

# OmniSharp-Vimのインストール，ビルド
ここが最も躓きました．

[VimでUnity C#のコーディングをするための設定 - Yucchiy's blog
](http://blog.yucchiy.com/2016/05/05/unity-vim-omnisharp/) に従っていくとビルドに失敗しました．
もとのインストールスクリプトは以下の用になっていました．

``` vim:vimrc
NeoBundleLazy 'OmniSharp/omnisharp-vim', {
      \   'autoload': { 'filetypes': [ 'cs', 'csi', 'csx' ] },
      \   'build': {
      \     'windows' : 'msbuild server/OmniSharp.sln',
      \     'mac': 'xbuild server/OmniSharp.sln',
      \     'unix': 'xbuild server/OmniSharp.sln',
      \   },
      \ }
```

まず一度目は，`msbuild not found` といった趣旨のエラーメッセージが発生しました．
[Omnisharp導入でハマったところ - 踊るプログラマー](http://waken.hatenablog.com/entry/2016/03/03/213256) でも同じようなエラーが出ており，MSBuild.exeの実行ファイルが存在するディレクトリをパスに追加すれば動いたとの報告もあったのですが，自分の環境では動作しませんでした．
そこで，NeoBundleのスクリプト内にMSBuild.exeのフルパスを渡すことでこのエラーは出力されなくなりました．
また，他のページでも書かれていたように`  /p:Platform="Any CPU" ` も追記したのですが，これが必須だったのかは確認できていません．

この状態でもビルドは通らなかったので，[VimでUnity C#のコーディングをするための設定 - Yucchiy's blog
](http://blog.yucchiy.com/2016/05/05/unity-vim-omnisharp/) を確認すると，2年前の時点ですがビルドが通らないと書かれており，[修正後のリポジトリ](https://github.com/yucchiy/omnisharp-vim)が上げられていたのでそちらを利用するとビルドすることができました

## 修正後のvimrc
上記の修正を踏まえて，以下のように修正を行った結果，OmniSharp-Vimのインストール及びビルドに成功しました．

``` vim:vimrc
NeoBundleLazy 'yucchiy/omnisharp-vim', {
      \   'autoload': { 'filetypes': [ 'cs', 'csi', 'csx' ] },
      \   'build': {
      \     'windows' : 'C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\MSBuild.exe server/OmniSharp.sln /p:Platform="Any CPU"',
      \     'mac': 'xbuild server/OmniSharp.sln',
      \     'unix': 'xbuild server/OmniSharp.sln',
      \   },
      \ }
```

## OmniSharp-Vimでオムニ補完を利用する
NeoCompleteをあまり使ったことがなかったので，一旦 [gvimでOmniSharpを使おうとすると“'omnifunc' は設定されていません”と出る - stack overflow](https://ja.stackoverflow.com/questions/5855/gvim%E3%81%A7omnisharp%E3%82%92%E4%BD%BF%E3%81%8A%E3%81%86%E3%81%A8%E3%81%99%E3%82%8B%E3%81%A8omnifunc-%E3%81%AF%E8%A8%AD%E5%AE%9A%E3%81%95%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%9B%E3%82%93%E3%81%A8%E5%87%BA%E3%82%8B)にかかれている設定を利用しました．

``` vim:vimrc
let g:acp_enableAtStartup = 0
let g:neocomplete#enable_at_startup = 1
let g:neocomplete#enable_smart_case = 1
let g:neocomplete#sources#syntax#min_keyword_length = 3
let g:neocomplete#lock_buffer_name_pattern = '\*ku\*'
let g:neocomplete#sources#dictionary#dictionaries = {
    \ 'default' : '',
    \ 'vimshell' : $HOME.'/.vimshell_hist',
    \ 'scheme' : $HOME.'/.gosh_completions'
    \ }
if !exists('g:neocomplete#keyword_patterns')
    let g:neocomplete#keyword_patterns = {}
endif
let g:neocomplete#keyword_patterns['default'] = '\h\w*'

autocmd FileType cs setlocal omnifunc=OmniSharp#Complete
if !exists('g:neocomplete#sources#omni#input_patterns')
  let g:neocomplete#sources#omni#input_patterns = {}
endif
let g:neocomplete#sources#omni#input_patterns.cs = '[^.]\.\%(\u\{2,}\)\?'
```
これで,コードを書いていくと，自動で補完が表示されます．

# Unityからgvimを起動可能にする．
Unityの`Edit`→`Preference`→`External Tool`→`External Script Editor`でデフォルトで使用するエディタを変更できますが，ここで直接gvim.exeを指定すると常に新規ウィンドウで開いて，複数ファイルの編集が面倒だったので既にgvimが起動されている場合はタブとして起動するように変更を加えました．
gvimを起動する`vim.bat`と，それをウィンドウ非表示のプロンプトから呼び出す`vim.vbs`の2つのスクリプトを作成し，Unityの`External Script Editor`には`vim.vbs`を選択します

``` bat:vim.bat
@echo off
"C:\Program Files\vim80-kaoriya-win64\gvim.exe" -p --remote-tab-silent "%1"
```

``` vb:vim.vbs
CreateObject("WScript.Shell").Run """C:\Program Files\vim80-kaoriya-win64\vim.bat """ & Wscript.Arguments(0) ,0
```
Program Filesにスペースが含まれているのでダブルクォートを3つ使用しています．
Vimのディレクトリへのパスは必要に応じて変更してください．

# 完成
これで，Unityのコーディングをgvimでできるようになりました．
まだVimの操作に十分慣れている状態ではありませんが，上達すれば，従来の環境よりも効率よくコーディングできると思います．