VSCode で Go の  Language Server  である gopls を有効にする

## gopls とは

[gopls](https://github.com/golang/tools/tree/gopls/v0.3.1/gopls)（Go Please）は Go が公式サポートしている Language Server です。現在開発が活発に進んでおり 2020年2月9日時点 での最新バージョンは v0.3.1 となっています。

## VSCode の Go拡張 における Language Server について

元々 VSCode の Go拡張である [microsoft/vscode-go](https://github.com/microsoft/vscode-go) のデフォルトの Language Server は [sourcegraph/go-langserver](https://github.com/sourcegraph/go-langserver) だったのですが、go-langserver の内部で利用されていた [nsf/gocode](https://github.com/nsf/gocode) の開発終了を受け、[こちら](https://github.com/microsoft/vscode-go/issues/2253) で話し合いがなされた末に 2019年3月に gopls へ [変更](https://github.com/microsoft/vscode-go/pull/2383) となりました。 

なお、2020年2月9日時点での vscode-go の最新バージョン v0.13.0 では、Language Server の使用が [デフォルト無効化](https://github.com/microsoft/vscode-go/blob/0.13.0/package.json#L1086-L1090) となっているので使用したい場合には有効化する必要があります。

## Language Server の有効化方法

[マニュアル](https://github.com/microsoft/vscode-go/tree/0.13.0#go-language-server) に従い VSCode で以下の作業を実施します。
VSCode に vscode-go がインストールされていない方はインストールを終えた後で実施してください。

### 1. Language Server の有効化

Code > Preferences > Settings （cmd+,） を開き `go.useLanguageServer` を検索して有効化する。
![スクリーンショット 2020-02-09 15.15.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49924/d9dc8513-cc23-79f8-108c-b48cd6b51ef1.png)


### 2. gopls のインストール

View > Command Palette （cmd+shift+P） を開き `Go: Install/Update Tools` を検索した後で `gopls` を選択してインストールする。
![スクリーンショット 2020-02-09 15.16.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49924/75c2daf0-ed26-2d00-7b2d-3d301546b60c.png)
![スクリーンショット 2020-02-09 15.16.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49924/8b45a8c8-6d1c-08bd-767e-3a11a57f776a.png)
![スクリーンショット 2020-02-09 15.16.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49924/8eb9deb8-7da5-e856-4df3-cc0768ff427d.png)

gopls v0.3.1 がインストールされました。

```bash
$ gopls version
golang.org/x/tools/gopls v0.3.1
    golang.org/x/tools/gopls@v0.3.1 h1:yNTWrf4gc4Or0UecjOas5pzOa3BL0WDDyKDV4Wz5VaM=
```

### 3. 任意の設定を適用

こちらは任意なのでスキップしても問題ないです。

View > Command Palette （cmd+shift+P） を開き `Preferences: Open Settings (JSON)` を検索して settings.json に任意の設定を適用する。[こちら](https://github.com/golang/tools/blob/gopls/v0.3.1/gopls/doc/vscode.md) を参考にして以下の設定を適用した例となります。

```js
// For gopls
"go.useLanguageServer": true,
"[go]": {
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
        "source.organizeImports": true,
    },
    // Optional: Disable snippets, as they conflict with completion ranking.
    "editor.snippetSuggestions": "none",
},
// Global settings for gopls
// https://github.com/golang/tools/blob/master/gopls/doc/settings.md
"gopls": {
    // === Officially supported Settings ===

    // This controls the information that appears in the hover text.
    "hoverKind": "SynopsisDocumentation",
    // If true, then completion responses may contain placeholders for function parameters or struct fields.
    "usePlaceholders": true,
    // This controls where points documentation for given package in `textDocument/documentLink`.
    "linkTarget": "pkg.go.dev",

    // === Experimental Settings ===

    // If true, it enables the use of the staticcheck.io analyzers.
    // Warning: This will significantly increase memory usage.
    "staticcheck": false,
    // If false, indicates that the user does not want documentation with completion results.
    "completionDocumentation": true,
    // If true, the completion engine is allowed to make suggestions for packages that you do not currently import.
    "completeUnimported": true,
    // If true, this turns on the ability to return completions from deep inside relevant entities, rather than just the locally accessible ones.
    "deepCompletion": true
}
```

![スクリーンショット 2020-02-09 15.37.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49924/4a6e287c-dbbd-26f4-faba-ce0b1c5b87b7.png)
![スクリーンショット 2020-02-09 15.39.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/49924/e926dad5-62d0-6d35-a060-be4008670b74.png)

### 4. 設定の適用

設定を適用するために VSCode を Reload する。これにより Language Server が有効化されます。開発が捗りそうです。

## おまけ: Go のコード補完ツールの歴史

[Big Sky :: gocode やめます(そして Language Server へ) ](https://mattn.kaoriya.net/software/lang/go/20181217000056.htm) がとてもわかりやすく非常に参考になったので、理解するがてら時系列を整理してみました。現時点では gopls を利用していくのが良さそうです。

1. Go 1.10 以前は gocode がデファクトスタンダード
2. Go 1.10 に追加されたビルドキャッシュの関係で gocode の開発が終了
3. それと同時に gocode を利用していた go-langserver の開発にも影響が出た
4. これらの状況を受けて gocode の fork で [mdempsky/gocode](https://github.com/mdempsky/gocode) や [stamblerre/gocode](https://github.com/stamblerre/gocode) が登場
5. Go の公式 Language Server として golsp が登場（stamblerre/gocode の人が開発を担当）
6. 別の Go の Language Server として [saibing/bingo](https://github.com/saibing/bingo) が登場
7. golsp 開発者が bingo 開発者にコラボレーションしようと [打診](https://github.com/saibing/bingo/issues/13) する
8. golsp が gopls（Go Please） に [rename される](https://github.com/golang/tools/commit/b258f6da23835bf37e95cc50af792447c7c67fe4)
9. コラボレーションが了承されて golang/tools を fork し bingo の機能を gopls に移植した [saibing/tools](https://github.com/saibing/tools) が登場