neovimにlspを利用したhaxe開発環境を構築する

## 概要

neovim上にlsp (language server protocol)を利用したhaxe開発環境を構築した。
これによりneovimで補完、定義元ジャンプ、変数リネーム等の機能を利用することができる。

コード補完

![haxe_lsp_comp.gif](https://qiita-image-store.s3.amazonaws.com/0/20591/d099aa9b-362e-fb49-330e-7f949bd32536.gif)

定義元ジャンプ
![haxe_lsp_jump.gif](https://qiita-image-store.s3.amazonaws.com/0/20591/2a622dd7-79a3-1d87-6588-4fa306b79ebf.gif)

変数リネーム
![haxe_lsp_rename.gif](https://qiita-image-store.s3.amazonaws.com/0/20591/32edc721-456c-bb2c-6740-da24b3405fff.gif)


## 環境

以下2つの環境で構築した。

* Windows10
* Arch Linux

利用したvim plugin

* jdonaldson/vaxe
    * haxeコードハイライト
* prabirshrestha/async.vim
    * vim-lspに必要
* prabirshrestha/vim-lsp
    * language server protocol client
* prabirshrestha/asyncomplete.vim
    * コード補完
* prabirshrestha/asyncomplete-lsp.vim
    * コード補完

## 手順

### Haxe Language Serverをビルドする

ビルドはWindows10上で実施し生成したjsをarch linuxにコピーした。
(haxe4環境がたまたまWindows10環境にあったのでそのまま利用しただけでどちらの環境でビルドしても問題ないと思う)

#### Haxe4をインストール

haxe-language-server をビルドするにはHaxe4が必要なのでインストールする。
Haxe公式からHaxe4のインストーラをDLし実行する

https://haxe.org/download/version/4.0.0-preview.5/

haxe4がインストールされ、正しくパスが通っているか確認する

```bash
>haxe -version
4.0.0-preview.5+7eb789f54
```

#### haxe-language-serverをビルド

https://github.com/vshaxe/haxe-language-server

cloneする（サブモジュールが含まれているので `--recursive` を付ける）

```bash
git clone https://github.com/vshaxe/haxe-language-server.git --recursive
cd haxe-languageserver
```

以下のコマンドでビルドする。
（ `.travis.yml` に記載されていたコマンド）

```bash
haxelib git vshaxe-build https://github.com/vshaxe/vshaxe-build
haxelib run vshaxe-build -t language-server -t language-server-tests -m both
```

ビルドが成功し `bin/server.js` が生成されていることを確認する。

### Arch Linuxに構築する手順

前提

* neovimインストール済み
* 前手順でビルドした `server.js` を配置済み

node.jsをインストールする

```bash
sudo pacman -S nodejs
```

必要なプラグインを記載。（プラグインマネージャーはdeinを利用）
`<<username>>` は自分の環境に合わせて置き換えてください。

```vim:~/.config/nvim/init.vim
set runtimepath+=/home/<<username>>/.cache/dein/repos/github.com/Shougo/dein.vim
 
 " Required:
 if dein#load_state('/home/<<username>>/.cache/dein')
   call dein#begin('/home/<<username>>/.cache/dein')
 
   call dein#add('jdonaldson/vaxe')
 
   call dein#add('prabirshrestha/async.vim')
   call dein#add('prabirshrestha/vim-lsp')
   call dein#add('prabirshrestha/asyncomplete.vim')
   call dein#add('prabirshrestha/asyncomplete-lsp.vim')

   " Required:
   call dein#end()
   call dein#save_state()
 endif
```

language serverの設定を記述

```vim:~/.config/nvim/init.vim
if executable('node')
    au User lsp_setup call lsp#register_server({
        \ 'name': 'haxe',
        \ 'cmd': {server_info->['node', '<<ビルドしたserver.jsを配置したパスを指定>>']},
        \ 'whitelist': ['haxe'],
        \ 'root_uri':{server_info->lsp#utils#path_to_uri(lsp#utils#find_nearest_parent_file_directory(lsp#utils#get_buffer_path(), 'build.hxml'))},
        \ 'initialization_options': {
        \    'displayServerConfig': {
        \        'env': {},
        \        'path': '/usr/bin/haxe',
        \        'arguments': []
        \    },
        \    'displayArguments': ['build.hxml']
        \ },
        \ 'workspace_config': {
        \    'haxe': {
        \       'enableDiagnostics': v:true,
        \       'diagnosticsPathFilter': '',
        \       'enableCodeLens': v:true,
        \       'displayPort': 'auto',
        \       'buildCompletionCache': v:true,
        \       'codeGeneration': {},
        \       'format': {}
        \    },
        \ }
    \ })
endif
```

プラグインのインストール。neovimで以下のコマンドを実行

```
:call dein#install()
```

あとは自分の好みに合わせてキーリマップしてください。

### Windows10 に構築する手順

前提

* neovimインストール済み
* node.jsインストール済み

必要なプラグインを記載。（プラグインマネージャーはdeinを利用）

```vim:~/.config/nvim/init.vim
if dein#load_state('~/.cache/dein')
  call dein#begin('~/.cache/dein')
  call dein#add('~/.cache/dein/repos/github.com/Shougo/dein.vim')
 
  call dein#add('jdonaldson/vaxe')
 
  call dein#add('prabirshrestha/async.vim')
  call dein#add('prabirshrestha/vim-lsp')
  call dein#add('prabirshrestha/asyncomplete.vim')
  call dein#add('prabirshrestha/asyncomplete-lsp.vim')

  " Required:
  call dein#end()
  call dein#save_state()
endif
```

language serverの設定を記述

```vim:~/.config/nvim/init.vim
if executable('node')
    au User lsp_setup call lsp#register_server({
        \ 'name': 'haxe',
        \ 'cmd': {server_info->['node', '<<ビルドしたserver.jsを配置したパスを指定>>']},
        \ 'whitelist': ['haxe'],
        \ 'root_uri':{server_info->lsp#utils#path_to_uri(lsp#utils#find_nearest_parent_file_directory(lsp#utils#get_buffer_path(), 'build.hxml'))},
        \ 'initialization_options': {
        \    'displayServerConfig': {
        \        'env': {},
        \        'path': 'C:\HaxeToolkit4\haxe\haxe.exe',
        \        'arguments': []
        \    },
        \    'displayArguments': ['build.hxml']
        \ },
        \ 'workspace_config': {
        \    'haxe': {
        \       'enableDiagnostics': v:true,
        \       'diagnosticsPathFilter': '',
        \       'enableCodeLens': v:true,
        \       'displayPort': 'auto',
        \       'buildCompletionCache': v:true,
        \       'codeGeneration': {},
        \       'format': {}
        \    },
        \ }
    \ })
    autocmd FileType haxe call s:configure_lsp()
endif
```

プラグインのインストール。neovimで以下のコマンドを実行

```
:call dein#install()
```

あとは自分の好みに合わせてキーリマップしてください。