(n)vi(m): Go plugins
Tags: go, vim
Published: 2021-01-11 11:04:51

The previous three posts covered all the basics I recommend when using nvim (or any vi(m) really). What's next are concrete plugins useful when programming in Go, specifically two plugins I use daily in nvim.

Please keep in mind that I use [`vim-plug`](https://github.com/junegunn/vim-plug) for installing plugins, so in the subsections below I will only indicate the corresponding command to use for `vim-plug` for installing them, but don't worry both plugins support different ways to get them installed.

The next gist contains all the configuration I use for both `vim-go` and `coc.nvim`, in the subsections below I will give you more context about specific configuration. 

<script src="https://gist.github.com/MarioCarrion/99f6a6110796cff5df118822472a0bc9.js"></script>

### 1) fatih/vim-go

[`vim-go`](https://github.com/fatih/vim-go) is nowadays the de-facto plugin for Go, it supports compiling, testing and executing Go programms, as well as running code coverage, looking up for documentation, symbol/definition declaration and more.

To install it use: 

```vim
Plug 'fatih/vim-go', { 'do': ':GoInstallBinaries' }
```

The configuration I use maps some keys for compiling, testing and running code coverage using the leader key:

```vim
function! s:build_go_files()
  let l:file = expand('%')
  if l:file =~# '^\f\+_test\.go$'
    call go#test#Test(0, 1)
  elseif l:file =~# '^\f\+\.go$'
    call go#cmd#Build(0)
  endif
endfunction

autocmd FileType go nmap <leader>b :<C-u>call <SID>build_go_files()<CR>
autocmd FileType go nmap <Leader>c <Plug>(go-coverage-toggle)
autocmd FileType go nmap <leader>t <Plug>(go-test)
```

Also I use some new commands for working with _alternate/test files_:

```vim
autocmd Filetype go command! -bang A call go#alternate#Switch(<bang>0, 'edit')
autocmd Filetype go command! -bang AV call go#alternate#Switch(<bang>0, 'vsplit')
autocmd Filetype go command! -bang AS call go#alternate#Switch(<bang>0, 'split')
autocmd Filetype go command! -bang AT call go#alternate#Switch(<bang>0, 'tabe')
```

This give us the following commands:

* `:A` for replacing the current buffer with the alternate test go. So if the file is `file.go` then `file_test.go` will be loaded.
* `:AV` similar to `:A` but now using a vertical split.
* `:AS` similar to `:A` but now using a horizontal split.
* `:AT` similar to `:A` but now opens up a new tab.

Next, we have:

```vim
let g:go_list_type = "quickfix"    " error lists are of type quickfix
let g:go_fmt_command = "goimports" " automatically format and rewrite imports
let g:go_auto_sameids = 1          " highlight matching identifiers
let g:go_def_mapping_enabled = 0   " coc.vim will do `gd`
```

The configuration above allows you to do the the following:

* Errors use [`quickfix`](https://neovim.io/doc/user/quickfix.html) for displaying errors,
* `goimports` is automatically called when saving a file,
* Matching identifiers are highlighted when cursor is on their name, and
* To disable `:GoDef` when calling `gd`, this is so `coc.nvim` can take over.

Alternatives to `vim-go` includes plugins like [govim](https://github.com/govim/govim) and [coc-go](https://github.com/josa42/coc-go).

### 2) neoclide/coc.nvim

[`neoclide/coc.nvim`](https://github.com/neoclide/coc.nvim) is a plugin for adding autocompletion that [supports language server protocol](https://github.com/neoclide/coc.nvim/wiki/Language-servers#supported-features), and therefore supports [`gopls`](https://github.com/golang/tools/blob/master/gopls/doc/vim.md#cocnvim)!

To install it, first make sure you install `nodejs`:

```vim
brew install nodejs
```

Then install the plugin:

```vim
Plug 'neoclide/coc.nvim', {'branch': 'release'}
```

The configuration below:

```vim
nmap <silent> gr <Plug>(coc-references)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> rn <Plug>(coc-rename)

nnoremap <silent> K :call <SID>show_documentation()<CR>
function! s:show_documentation()
  if (index(['vim','help'], &filetype) >= 0)
    execute 'h '.expand('<cword>')
  else
    call CocAction('doHover')
  endif
endfunction
```

Let's you do the following:

* `gr` Lists all the references to the selected symbol, for example other types using said type,
* `gi` Works for interface types, it allows you to list types implementing selected interface,
* `rn` Works for types, it allows you to rename types, this is similar to `:GoRename` (but this one works), and
* `Z` displays documentation for the selected type.

I highly encourage you to take a look at the [example vim configuration](https://github.com/neoclide/coc.nvim#example-vim-configuration) because there are some nice settings that could improve your vim performance.

An alternative plugin to to `coc.nvim` is [`Shougo/deoplete.nvim`](https://github.com/Shougo/deoplete.nvim) which also supports multiple programming languages.

### Finally let's see vim-go and coc.nvim in actioa!

Quick show-and-tell of using both plugins:

<a data-flickr-embed="true" href="https://www.flickr.com/photos/mariocarrion/50014660781/in/album-72157668921618444/" title="go-vim + coc.nvim"><img src="https://live.staticflickr.com/31337/50014660781_4136a633f0_o.jpg" width="640" height="426" alt="go-vim + coc.nvim"></a><script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script>

---

![The more you know](https://media.giphy.com/media/83QtfwKWdmSEo/giphy.gif "The more you know")