VSCodeでGoのModules設定

VSCodeでGoの[Modules](https://github.com/golang/go/wiki/Modules)がサポートされているという情報を目にしたので設定してみました。
https://github.com/Microsoft/vscode-go/wiki/Go-modules-support-in-Visual-Studio-Code

## 環境

* macOS 10.12.4
* Go 1.11.5
* Visual Studio Code 1.13.1
* vscode-go 0.9.2

`go mod init`, `go build`などでモジュールをすでに配置してある状態から開始します。

## Install/Update Tools

コマンドパレットから`Go: Install/Update Tools`でツール類をひととおり最新にします。
![update_tools.png](https://qiita-image-store.s3.amazonaws.com/0/117117/b94552a5-ed5e-4314-a0d4-7523b17bd980.png)

## cannot find package

ツール類を最新にするだけではパッケージが見つからないので環境変数`GO111MODULE`を設定します。

```json:settings.json
{
    "go.toolsEnvVars": {"GO111MODULE": "on"},
}
```

ここまでで設定完了となることもあるようです。まだエラーが出る場合は次へ

## permission denied

私の環境ではこのエラーに遭遇しました。

```bash
go build golang_org/x/crypto/cryptobyte/asn1: open /usr/local/go/pkg/darwin_amd64/vendor/golang_org/x/crypto/cryptobyte/asn1.a: permission denied
```

ファイル保存時のビルドでエラーになるようです。
`go.buildOnSave`を`off`にするとエラーは消えますが今度はlintなどが効かなくなってしまうため、以下を設定します。

```json:settings.json
{
    "go.installDependenciesWhenBuilding": false,
}
```

## 既知の不具合

以上でおおよそ動くようになると思います。が、モジュールへの定義ジャンプにはまだ不具合があるようです。
https://github.com/Microsoft/vscode-go/issues/2296

1回目のジャンプはOK、2回目以降はジャンプできない
これは私の環境でも再現しました。

## 追記: go.formatTool

`go.formatTool`のデフォルト設定`goreturns`はModulesに対応していないようなので代わりに`goimports`を設定しておくとよさそうです。
https://github.com/Microsoft/vscode-go/issues/2309

```json:settings.json
{
    "go.formatTool": "goimports",
}
```

設定変更後`Go: Install/Update Tools` > `goimports`を選択、インストール

＃そしておそらく近々`goimports`がデフォルトになりそう
https://github.com/Microsoft/vscode-go/pull/2338

## 追記: go.modが空だと補完されない

新規のプロジェクトで`go mod init`して空の`go.mod`を生成した状態では、`$GOPATH/pkg/mod`以下にパッケージを配置してあってもコードの補完が効きません。
補完を効かせるためにはあらかじめ`go get -u xxx`などで`go.mod`にrequireの記述を追加しておく必要があります。

## 追記: Language Serverを使う

コード補完のツールとして`gocode`の代わりにLanguage Serverを使うこともできます。
現時点では[bingo](https://github.com/saibing/bingo)がLanguage Serverの選択肢になります。
Language Serverまわりの設定

```json:settings.json
{
    "go.useLanguageServer": true,
    "go.alternateTools": {
        "go-langserver": "bingo"
    },
    "go.languageServerFlags": [
        "-enhance-signature-help",
        "-trace",
        "-format-style=goimports",
    ],
    "go.languageServerExperimentalFeatures": {
        "format": true,
        "autoComplete": true,
        "rename": true,
        "goToDefinition": true,
        "hover": true,
        "signatureHelp": true,
        "goToTypeDefinition": true,
        "goToImplementation": true,
        "documentSymbols": true,
        "workspaceSymbols": true,
        "findReferences": true
    },
}
```

[bingo](https://github.com/saibing/bingo)をインストール

```bash
$ git clone https://github.com/saibing/bingo.git
$ cd bingo
$ GO111MODULE=on go install
```

vscodeをリロードして反映

### 使用感

上記設定でコード補完などをためしてみましたが、いろいろ動かない・・・
気づいた点だけ挙げると

* `goimports`が効かない  
formatの設定はfalseにしたほうがよさそう
* ビルド時にエラーがないはずなのにエラーと指摘されてしまうことがある  
importで別名を使っているとエラーになるような？？
* $GOPATH/pkg/mod以下に同名のパッケージが混在すると片方しか補完されない  
[cenk/backoff](https://github.com/cenk/backoff)と[cenkalti/backoff](https://github.com/cenkalti/backoff)が混在していてはまりました

安定するまではLanguage Server版は少し様子見のほうが無難かもしれません。

## 参考
* https://github.com/Microsoft/vscode-go/wiki/Go-modules-support-in-Visual-Studio-Code
* https://github.com/Microsoft/vscode-go/issues/1532
* https://github.com/Microsoft/vscode-go/issues/1874
* https://github.com/Microsoft/vscode-go/issues/2296