vim-goを使うなら使用したいコマンド集と設定

こんにちわ

最近NeoVimに乗り換えて、vim-goプラグインを使用しています。

vimmerとgopherにとって素晴らしいプラグインなので、
共有と自分用メモという意味で記事を書いています。

各項目をクリックすると詳細説明に飛びます。
tutorialの[日本語訳](https://github.com/hnakamur/vim-go-tutorial-ja)も合わせて読むと良いと思います。

# 目次
- [コマンド集](#コマンド集)
    - [定義へ移動](#定義へ移動)
    - [移動から戻る](#移動から戻る)
    - [画面分割して定義へ移動](#画面分割して定義へ移動)
    - [インターフェイス実装一覧](#インターフェイス実装一覧)
    - [定義参照一覧](#定義参照一覧)
    - [タグ生成](#タグ生成)
    - [タグの削除](#タグの削除)
    - [キーなしの構造体定義にキーを追加](#キーなしの構造体定義にキーを追加)
    - [構造体のキー初期値を追加](#構造体のキー初期値を追加)
    - [`if err != nil`を追加](#if-err--nilを追加)
    - [構文チェック](#構文チェック)
    - [実行](#実行)
    - [テスト実行](#テスト実行)
    - [テスト個別実行](#テスト個別実行)
    - [カバレッジを見る](#カバレッジを見る)
    - [カバレッジをブラウザで見る](#カバレッジをブラウザで見る)
    - [関数と型宣言一覧](#関数と型宣言一覧)
    - [インターフェイスのメソッド雛形生成](#インターフェイスのメソッド雛形生成)
    - [リネーム](#リネーム)
    - [テキストオブジェクト](#テキストオブジェクト)
- [設定](#設定)
    - [スニペット](#スニペット)
    - [保存時自動Import](#保存時自動import)
    - [保存時チェック](#保存時チェック)
    - [GoRunやGoTest時の画面分割方法変更](#gorunやgotest時の画面分割方法変更)
    - [よく使うコマンドをキーマッピングしておく](#よく使うコマンドをキーマッピングしておく)

- [パワー不足マシンでの定義ジャンプ速度改善](#パワー不足マシンでの定義ジャンプ速度改善)


# コマンド集
## [定義へ移動](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L257)
定義や構造体の定義もとへのジャンプは変数にカーソルを当てた状態で、
<kbd>Ctrl</kbd>+<kbd>[</kbd>もしくは`GoDef`で定義もとへのジャンプする。
![godef.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/d40dd3ce-a11a-7e80-87f5-467d339d0c2a.gif)


## [移動から戻る](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L307)
定義ジャンプするとジャンプ履歴がスタックされる。
一つ前に戻るときは<kbd>Ctrl</kbd>+<kbd>t</kbd>もしくは`GoDefPop`。
もしくはvimの標準機能のカーソルを一つ前に戻す<kbd>Ctrl</kbd>+<kbd>o</kbd>。
![godefpop.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/9cfd9c01-a4f0-6526-eedc-42118c232d78.gif)


## [画面分割して定義へ移動](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L902)
以下のようにキーマッピングすることで、<kbd>Space</kbd>+<kbd>s</kbd>や<kbd>Space</kbd>+<kbd>v</kbd>で画面を分割した状態で定義への移動できる。

```vim
let mapleader = "\<Space>"

au FileType go nmap <leader>s <Plug>(go-def-split)
au FileType go nmap <leader>v <Plug>(go-def-vertical)
```

![go-def-split.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/29ee271e-c541-98fe-0dd0-49a5f73b82a0.gif)
![go-def-split.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/b4982e51-9376-aa9d-555a-cb9865b9b072.gif)

## [インターフェイス実装一覧](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L512)
インターフェイス名にカーソルを当てた状態で`GoImplements`で実装済みの構造体一覧をFixリストに表示する。
![go-implements.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/78d1ca40-37a9-7d13-fc51-d331e4b847c9.gif)

## [定義参照一覧](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L610)
変数や関数の定義にカーソルを当てた状態で`GoReferrers`で定義への参照をFixリストに表示する。
リファクタリング時やバグ範囲調査時に活用。

![go-referrences.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/d6184b90-f8ee-03a8-5949-4bbf870d2b79.gif)

## [タグ生成](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L753)
構造体のキーにカーソルを当てた状態で`GoAddTags`でタグを自動生成。
タグ名を指定したときは`GoAddTags url`というふうにすればOK。
![goaddtag.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/9e015993-7853-b776-ed72-f316d8ab39ed.gif)

## [タグの削除](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L780)
構造体のキーにカーソルを当てた状態で`GoRemoveTags`でタグを削除してくれる。
![go-remove-tag.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/73e978b2-b288-aa9b-abef-4840debf5728.gif)

## [キーなしの構造体定義にキーを追加](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L833)
構造体定義にカーソルを当てた状態で、`GoKeyify`でキー名を追加してくれる。
![go-keyify.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/8399312e-ecc2-02cf-03b4-2298c628561e.gif)

## [構造体のキー初期値を追加](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L849)
構造体定義にカーソルを当てた状態で`GoFillStruct`で型に合わせて初期値を追加してくれる。
![go-fillstruct.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/00c084bf-7a52-8281-654d-81e310155b0d.gif)

## [`if err != nil`を追加](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L868)
`GoIfErr`で以下のスニペットを追加。
戻り値は関数の戻り値定義に合わせて追加いしてくれるあたりが賢いが、追加してくれない型もある。

```go
if err != nil {
	return err
}
```
vim-goは簡単にスニペット導入できるので後ほど紹介します。
![go-iferr.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/8151aec9-2714-68b2-cd91-92946bcbce7b.gif)

## [構文チェック](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L242)
`GoVet`で構文が間違っていないかをチエック。間違っている場合はFixリストに表示する。
![govet.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/1a1681c5-d15c-9e68-e87f-e733af8f484b.gif)

## [実行](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L324)
`GoRun`でmainパッケージビルドして実行する。
![gorun.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/7c17175a-96e1-67cc-0d91-6345f5e59c60.gif)


## [テスト実行](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L385)
`GoTest`でテストを実行する。
![go-test.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/7e655c05-8a67-f1d9-2634-da91aef7c59f.gif)

## [テスト個別実行](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L405)
`GoTestFunc`で関数毎のテストを実行する。
![go-testfunc.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/a53fbf8f-be70-cbe8-160b-03a36f0e1695.gif)

## [カバレッジを見る](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L436)
`GoCoverage`でストを実施してカバレッジを色つけて表示してくれる。
![go-cavarage.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/3c1b1657-aca4-2c5f-f12c-e5e5f4f15290.gif)

## [カバレッジをブラウザで見る](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L458)
`GoCoverageBrowser`でテストを実施してカバレッジをデフォルトブラウザで見る。
![go-covarage-brewoser.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/80e4aa1f-9c47-4dcd-26a9-76e379d30ebc.gif)

## [関数と型宣言一覧](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L703)
※`ctrlp.vim`もしくは`fzf`プラグインを入れる必要がある。
`GoDecls`で開いているファイル、`GoDeclsDir`でディレクトリ配下の関数と型宣言を表示してくれる。
![godecls.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/7eca1db6-6f95-d949-991e-4c44e10e9fc7.gif)

## [インターフェイスのメソッド雛形生成](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L742)
`GoImpl`で構造体とインターフェイスを指定することで、実装すべきメソッドの雛形を生成してくれる。
標準パッケージの場合は不要だけど、自パッケージの場合は`$GOPATH/src以下のパス.インターフェイス名`を入力する必要がある。

例)
githu.com/skanehira/docui/panelのPanelインターフェイスを実装したい場合は以下のように入力すればOK。
`github.com/skanehira/docui/panel.Panel`
![go-impl.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/8019a98a-d19c-7280-6550-43e0af523993.gif)

## [リネーム](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L518)
一括で変数名や関数名などを変えたい時に、カーソルを当てた状態で`GoRename`で変更できる。
![go-rename.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/06c6c68a-7b0d-4aff-e7f5-2392404f83bc.gif)

## [テキストオブジェクト](https://github.com/hnakamur/vim-go-tutorial-ja#%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88-)
関数にカーソルを当てた状態で`vif`などで一括選択できる。
![dif.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/6b7fe62d-15f6-d336-6bcb-bf7a27b39fd9.gif)

| command | opration |
|:-:|:-:|
| vif  | 関数の内側を全選択  |
| cif  | 関数の内側を全カット  |
| dif  | 関数の内側を全削除  |
| yif  | 関数の内側をヤンク  |
| vaf  | 関数全体を選択  |
| caf  | 関数全体をカット  |
| daf  | 関数全体を削除  |
| yaf  | 関数全体をヤンク  |

# 設定
## [スニペット](https://github.com/hnakamur/vim-go-tutorial-ja#%E3%82%B9%E3%83%8B%E3%83%9A%E3%83%83%E3%83%88-)
プラグイン`'SirVer/ultisnips'`を追加するだけでスニペットを使用することができる。
`fn`を入力して<kbd>Tab</kbd>を押すと`fmt.Println("")`という感じで補完してくれる。
デフォルトで使えるスニペット一覧は[こちら](https://github.com/fatih/vim-go/blob/master/gosnippets/UltiSnips/go.snippets)。
自前で用意する時は↑のファイルに追記すればOK。

![go-snipet.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/55621f02-1494-3987-077d-2e6cbc8a8d4c.gif)

スニペットによっては複数入力しないといけないモノがあるので、
`vimrc`もしくは`vim.init`に以下を追加すると<kbd>Tab</kbd>と<kbd>Shift</kbd>+<kbd>Tab</kbd>で入力の選択ができるようになる。

```vim
let g:UltiSnipsExpandTrigger="<tab>"                                            
let g:UltiSnipsJumpForwardTrigger="<tab>"                                       
let g:UltiSnipsJumpBackwardTrigger="<s-tab>"  
```
![snipet-select.gif](https://qiita-image-store.s3.amazonaws.com/0/66178/0047e6cc-a52d-043a-eea8-bc1fe5215fc2.gif)


## [保存時自動Import](https://github.com/hnakamur/vim-go-tutorial-ja#import%E6%96%87-)
`vimrc`や`init.vim`に以下を追加するとファイル保存時に自動でパッケージをimportしてくれる。

```vim
let g:go_fmt_command = "goimports"
```

## [保存時チェック](https://github.com/hnakamur/vim-go-tutorial-ja#%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%81%99%E3%82%8B-)
`vimrc`や`init.vim`に以下を追加するとファイル保存時に`GoLint`、`GoVet`、`GoErrCheck`をまとめてしてくれる。

```vim
let g:go_metalinter_autosave = 1
```

パワーがないマシンだと時間かかるので、構文チェックだけしたい場合は以下のようにすればOK。

```vim
let g:go_metalinter_autosave = 1
let g:go_metalinter_autosave_enabled = ['vet']
```

## [GoRunやGoTest時の画面分割方法変更](https://github.com/fatih/vim-go/blob/master/doc/vim-go.txt#L1559)
`vimrc`や`init.vim`に以下を追加することで、分割方法を変更できる。
上下に分割して実行させたいので以下のようにしている。

```vim
let g:go_term_mode = 'split'
```

## よく使うコマンドをキーマッピングしておく

```vim
au FileType go nmap <silent> <leader>r <Plug>(go-run)
au FileType go nmap <silent> <Leader>s <Plug>(go-def-split)
au FileType go nmap <silent> <Leader>v <Plug>(go-def-vertical)
au FileType go nmap <silent> <leader>t <Plug>(go-test)
au FileType go nmap <silent> <leader>at :GoAddTags<CR>
au FileType go nmap <silent> <leader>fs :GoFillStruct<CR>
au FileType go nmap <silent> <leader>ei :GoIfErr<CR>
au FileType go nmap <silent> <leader>ki :GoKeyify<CR>
au FileType go nmap <silent> <leader>dd :GoDeclsDir<CR>
au FileType go nmap <silent> <leader>ip :GoImpl<CR>
（中略）
```

# パワー不足マシンでの定義ジャンプ速度改善
パワーがなく、定義ジャンプなどに時間が掛かってストレスになる方は、LSPを試してみてください。
詳細は[こちらの記事](https://qiita.com/gorilla0513/items/783836797ff84a3a4753)を参照してください。

自分の環境では処理速度が改善され、ジャンプが早くなりましたが、
それなりのパワーがあるPCだと逆にvim-goの定義ジャンプの方が早かったりします。