I’m getting questions quite often about how my is configured for Go development. So in this article I intend to describe just that. In the interest of brevity I’ll not cover the setup in general, but rather the Go parts in particular. neovim My setup is based on . Most of the things below should work well on vim too, except the debugger and code completion (which can be solved otherwise in vim — but I’m not covering that here). neovim All of my dotfiles are . here on GitHub Basic vim-go setup configuration is the great product of and it’s the de-facto standard for Go developers in (neo)vim. I’m gonna run you through the basic vim-go configuration I’ve made to have a great development environment. [vim-go](https://github.com/fatih/vim-go) Fatih Arslan Configure indentation I’m using tabs and a tab width of 4 for my source files. Here’s the configuration for setting that for all your Go files. au FileType go set noexpandtabau FileType go set shiftwidth=4au FileType go set softtabstop=4au FileType go set tabstop=4 Code highlighting I like colors and I believe they are generally very helpful when developing to distinguish between various entities in the code. So I have enabled a lot of the available highlighting options in vim-go. let g:go_highlight_build_constraints = 1let g:go_highlight_extra_types = 1let g:go_highlight_fields = 1let g:go_highlight_functions = 1let g:go_highlight_methods = 1let g:go_highlight_operators = 1let g:go_highlight_structs = 1let g:go_highlight_types = 1 This will highlight fields, functions, methods, operators, structs, types and such. I have also enabled highlighting of variables that are the same. So if I have the cursor over the variable , other uses of that variable within the viewport will be highlighted. See the example below: actualData To enable it, add: let g:go_auto_sameids = 1 Auto import dependencies One of the things I liked about Go when I came from a Python background was the auto import of dependencies. It’s sometimes a little frustrating when the wrong package is imported. But mostly it boosts my productivity. Auto import is a feature of and you can enable it in vim like this: gofmt let g:go_fmt_command = "goimports" Now you’ll get the dependencies imported when you save the file. Linting code I’m using to lint code for all languages I code in. It works pretty well right out of the box, I have made only a few small adjustments to make it look nicer and integrate with . is asynchronous, so it’s not interfering too much with your coding. [ale](https://github.com/w0rp/ale) [airline](https://github.com/vim-airline/vim-airline) ale " Error and warning signs.let g:ale_sign_error = '⤫'let g:ale_sign_warning = '⚠' " Enable integration with airline.let g:airline#extensions#ale#enabled = 1 Warning from ALE for an optimization that can be made in the code. Navigation I haven’t customized much when it comes to navigation. But I wanted to highlight a few things that are useful: takes you to the next function or method ]] takes you to the previous function or method [[ The above two things are handy and comes out of the box. But they are limited to the functions or methods defined in the file you have open. Personally I try to have a minimal number of functions in each file and rather have many files. Then I want to be able to search and easily navigate between the function definitions . within the package That can be achieved using . For that you have to have installed along with . :GoDeclsDir [ctrlp](https://github.com/ctrlpvim/ctrlp.vim) vim-go I have added a key mapping to for this: ,gt au FileType go nmap <leader>gt :GoDeclsDir<cr> Running tests I’m writing a lot of tests cases and thus working a lot with switching back and forth between the implementation and the test. vim-go provides a command called , which switches to the test case if you’re in the implementation and vice versa. This is really handy and I use it a lot, so I have added a keybinding for it: :GoAlternate au Filetype go nmap <leader>ga <Plug>(go-alternate-edit)au Filetype go nmap <leader>gah <Plug>(go-alternate-split)au Filetype go nmap <leader>gav <Plug>(go-alternate-vertical) So now I just do to switch to the test ( is my leader key) or / to open in a vertical / horizontal split. ,ga , ,gav ,gah I have also mapped the command to . Notice though that I’m adding the flag in order to only run tests in short mode in my editor. This would typically by-pass tests that has a third party dependency like a database or so. :GoTest <F10> -short au FileType go nmap <F10> :GoTest -short<cr> Finally what I use quite much is code coverage reports, both for my own development and for code reviews, to identify what parts of the code has not been properly covered by tests. I have that mapped to , right next to the regular tests. <F9> au FileType go nmap <F9> :GoCoverageToggle -short<cr> The result of a coverage report could look something like this. The implementation is on the left hand side and the tests on the right hand side Pressing again will remove the green and red coloring. <F9> Working with types and definitions Show type information in status line One of the neat little things I use all the time is to move the cursor over a variable or such to see what type it is. Or move it to a function call and see it’s input parameters and return values. actualData is a byte slice in this case It’s really one of these basic sanitary features that should be enabled. Enable it with: let g:go_auto_type_info = 1 Get the documentation I often find my self needing more details about certain functions or so. There is a built-in support which works great out of the box in vim-go. Simply press when over a type or function to get more details. K Go to definition Go to definition is something I do a whole lot, so therefor I’ve added a mapping for that on . <F12> au FileType go nmap <F12> <Plug>(go-def) It takes me to the definition of whatever I have under my cursor. When I need to get back I press . C-t Code completion I’m — just like the neovim community in general it seems — using to power all my completion needs for all languages. To make it run with Go you also need to install . [deoplete](https://github.com/Shougo/deoplete.nvim) [deoplete-go](https://github.com/zchee/deoplete-go) To enable by default, add this to your configuration: deoplete if has('nvim')" Enable deoplete on startuplet g:deoplete#enable_at_startup = 1endif It will look something like this in action: Also, you will find that crashes a whole lot if you are also using multiple cursors ( ). To prevent that, disable the completion when in multi cursor mode: deoplete [terryma/vim-multiple-cursors](https://github.com/terryma/vim-multiple-cursors) " Disable deoplete when in multi cursor modefunction! Multiple_cursors_before()let b:deoplete_disable_auto_complete = 1endfunction function! Multiple_cursors_after()let b:deoplete_disable_auto_complete = 0endfunction Adding JSON tags to structs For those who are working on JSON API’s it’s often cumbersome to define s and manually type all the JSON tags as well. is here to the rescue! If you have a like this: struct vim-go struct type jCreateInvoiceResponse struct {Invoice jInvoicePaymentMethods []jPaymentMethod} You’d want to convert it to type jCreateInvoiceResponse struct {Invoice jInvoice `json:"invoice"`PaymentMethods []jPaymentMethod `json:"payment_methods"`} To accomplish that, run . My APIs usually want properties, but it also supports . Set your preference using :GoAddTags snakecase camelcase let g:go_addtags_transform = "snakecase" Here’s the feature in action for the above : struct Snippet driven development For a long time I did not use snippets when coding. Largely because I didn’t understand how useful they can be. But at the end of the day you’re repeating patterns in your code over and over. For these patterns, it’s really efficient to have snippets that fills out the generic parts. I’m using for my development. It’s basic and foremost, it’s easy to write your own snippets. The gist of it is that you write a keyword and then press , to “expand” the snippet. There might be multiple places for inserting your code. You can move to the next by hitting again. [neosnippet](https://github.com/Shougo/neosnippet.vim) C-k C-k To enable for , add this line: neosnippet vim-go let g:go_snippet_engine = "neosnippet" You need to install separately from . And you should also make sure to install , which provides you with a set of default snippets for a long list of languages. neosnippet vim-go [neosnippet-snippets](https://github.com/Shougo/neosnippet-snippets) Here are a couple of the most powerful snippets I use: expands to ts type | struct expands to ti type | interface adds boilerplate code for a table based unit test. This is my own custom snippet, it’s not part of . You can find it in my . [funcTest](https://github.com/sebdah/dotfiles/blob/master/config/nvim/snippets/go.snip#L22) neosnippet-snippets dotfiles expands to a type pattern ife if err != nil { | } I’d really advice you to take some time and learn to use snippets, it’s truly a time saver. Debugging Go code I’m hoping to cover more about how to debug Go applications in a later article. But in this one we’re only gonna touch upon how to dress neovim for success in the field. Firstly, you’d need to install on your machine. Refer to their for details. [delve](https://github.com/derekparker/delve/) installation documentation The other thing you’d need is my package which is utilizing some neovim features to integrate with . So unfortunately this package does not work on regular vim. [vim-delve](https://github.com/sebdah/vim-delve) delve With the dependencies installed you can now start debugging your Go code. You can add breakpoints with . Then you’d start the debugger with either or (if you are debugging a non- package use ). :DlvToggleBreakpoint :DlvDebug :DlvTest main :DlvTest Tracepoints are also supported. They can be toggled in code using . A tracepoint is not stopping your execution, it just prints a note that the tracepoint was hit. :DlvToggleTracepoint An example of in action: delve Code to the left with a breakpoint (●) and a tracepoint (◆). Delve output to the right. The End There is so much more about vim that I’d love to write about. But at some point I’d probably diverge too much away from to Go subject in this article. Anyhow, my (and my )holds all details so you could always dig deeper there for more details on my setup. [dotfiles](https://github.com/sebdah/dotfiles) [init.vim](https://github.com/sebdah/dotfiles/blob/master/config/nvim/init.vim) : Changed the linting section to replace direct use of with . Update 9/7–2017 gometalinter ale