Skip to content

Instantly share code, notes, and snippets.

@cridenour
Last active August 7, 2023 13:52
Show Gist options
  • Save cridenour/74e7635275331d5afa6b to your computer and use it in GitHub Desktop.
Save cridenour/74e7635275331d5afa6b to your computer and use it in GitHub Desktop.
Setting up Vim as your Go IDE

Setting up Vim as your Go IDE

The final IDE

Intro

I've been wanting to do a serious project in Go. One thing holding me back has been a my working environment. As a huge PyCharm user, I was hoping the Go IDE plugin for IntelliJ IDEA would fit my needs. However, it never felt quite right. After a previous experiment a few years ago using Vim, I knew how powerful it could be if I put in the time to make it so. Luckily there are plugins for almost anything you need to do with Go or what you would expect form and IDE. While this is no where near comprehensive, it will get you writing code, building and testing with the power you would expect from Vim.

Getting Started

I'm assuming you're coming with a clean slate. For me this was OSX so I used MacVim. There is nothing in my config files that assumes this is the case.

We're going to need a version of Vim 7.4 with lua support.

brew install macvim --with-cscope --with-lua

While we're at it, let's replace our command line Vim with one that has lua support as well.

brew install vim --with-lua --override-system-vim

Now most of my .vimrc is from this fantastic repo. However, my fork makes a few changes.

  • Updated plugins to their latest and greatest
  • A quick bugfix for Vim 7.4 support in vim-zenroom2
  • Changed file explorer from NERDTree to netrw
  • Added neocomplete for autocompletion
  • Changes from vim-golang to vim-go
  • Updated taglist.vim to understand Go

Following their instructions, you can get this going with two commands.

git clone git://github.com/cridenour/vimrc.git ~/.vim_runtime
sh ~/.vim_runtime/install_awesome_vimrc.sh

Changes Explained

I didn't want to change from the default .vimrc from amix's repo without reason as they have great reasons for each of their plugin choices.

vim-zenroom2 Bugfix

Using the latest release of Vim 7.4 meant an incompatibility with zenroom2, mainly the names of their functions. I followed a pull request that has yet to make it upstream in the project.

NERDTree -> netrw

NERDTree is a fantastic plugin but does not allow you to keep it open in a split window. Using netrw, I can use a split window to always show the file structure and even manage the window that the files open in.

Add neocomplete

There are lots of competing autocomplete, including stock Vim. However, using Ctrl-X Ctrl-O was more of an interruption than anything. Neocomplete was fast (with lua) and highly configurable.

Vim-golang -> Vim-go

Vim-golang is a mirror of the stock files provided with Go. Vim-go provides autocomplete support, ability to go to the documention, gofmt on save and more. Integrates nicely with neocomplete.

Mappings

I use some default mappings for neocomplete as well as some Vim-go mappings. These should go in your ~/.vim_runtime/my_configs.vim

 " Disable AutoComplPop.
 let g:acp_enableAtStartup = 0
 " Use neocomplete.
 let g:neocomplete#enable_at_startup = 1
 " Use smartcase.
 let g:neocomplete#enable_smart_case = 1
 " Set minimum syntax keyword length.
 let g:neocomplete#sources#syntax#min_keyword_length = 3
 
 " Plugin key-mappings.
 inoremap <expr><C-g>     neocomplete#undo_completion()
 inoremap <expr><C-l>     neocomplete#complete_common_string()
 
 " Recommended key-mappings.
 " <CR>: close popup and save indent.
 inoremap <silent> <CR> <C-r>=<SID>my_cr_function()<CR>
 function! s:my_cr_function()
     return neocomplete#close_popup() . "\<CR>"
 endfunction
 " <TAB>: completion.
 inoremap <expr><TAB>  pumvisible() ? "\<C-n>" : "\<TAB>"
 " <C-h>, <BS>: close popup and delete backword char.
 inoremap <expr><C-h> neocomplete#smart_close_popup()."\<C-h>"
 inoremap <expr><BS> neocomplete#smart_close_popup()."\<C-h>"
 inoremap <expr><C-y>  neocomplete#close_popup()
 inoremap <expr><C-e>  neocomplete#cancel_popup()
 
 " Go related mappings
 au FileType go nmap <Leader>i <Plug>(go-info)
 au FileType go nmap <Leader>gd <Plug>(go-doc)
 au FileType go nmap <Leader>r <Plug>(go-run)
 au FileType go nmap <Leader>b <Plug>(go-build)
 au FileType go nmap <Leader>t <Plug>(go-test)
 au FileType go nmap gd <Plug>(go-def-tab)

The most used are ,r for running the current file, ,t for testing the current package, ,gd for reading the documentation.

Getting Go Structure with ctags

Using ctags can provide structure information to use with taglist, provided in our vimrc. This is a big part of how I use an IDE and I wanted it to work with Go. Unfortunately, all the versions I could find did not come with Go tags. It took some searching to find exactly what I needed to get this working.

First you need to set up ctags to understand Go. You can do this with a configuration file at ~/.ctags

--langdef=Go
--langmap=Go:.go
--regex-Go=/func([ \t]+\([^)]+\))?[ \t]+([a-zA-Z0-9_]+)/\2/f,func/
--regex-Go=/var[ \t]+([a-zA-Z_][a-zA-Z0-9_]+)/\1/v,var/
--regex-Go=/type[ \t]+([a-zA-Z_][a-zA-Z0-9_]+)/\1/t,type/

I also had to update taglist.vim. If you start from my fork, this is done for you.

" go language
let s:tlist_def_go_settings = 'go;g:enum;s:struct;u:union;t:type;' .
                           \ 'v:variable;f:function'

Setting up the IDE windows

I wanted to use Vim as normal in most cases, but when I need my IDE, I can hit ,, and get the windows I need. A file explorer set to open all files in the main buffer window, a tag list of the current file and your main buffer.

This will also go in your ~/.vim_runtime/my_configs.vim

 " Netrw Style Listing
 let g:netrw_liststyle = 3
 
 nnoremap <Leader><Leader> :Tlist<CR><C-W>h<C-W>s:e .<CR><C-W>l:let g:netrw_chgwin=winnr()<CR><C-W>h

Summary

This setup works for me, but might not for you. Hopefully you can use this as a starting point.

@dgryski
Copy link

dgryski commented Jun 13, 2014

For generating tags files, there's also https://github.com/jstemmer/gotags

@cridenour
Copy link
Author

@dgryski: That looks awesome. I'll have to take a look.

@adrianduke
Copy link

With gotags installed I adjusted the IDE windows command to as follows:

" Netrw Style Listing
let g:netrw_liststyle = 3
nnoremap <Leader><Leader> :TagbarOpen<CR><C-W>l<C-W>s:e .<CR><C-W>h:let g:netrw_chgwin=winnr()<CR><C-W>l

I also removed the modifications from ~/.ctags.

Appears to work fine, except the windows appear on the right (which is fine for me).

@jpleau
Copy link

jpleau commented Jun 14, 2014

What is the font used in your screenshot?

@cridenour
Copy link
Author

Adobe Source Code Pro. The config files are ready to use it if it's installed.

@chriskaukis
Copy link

My only suggestion is that ctrl+f and ctrl+b are default Vim bindings for forward and back pages. Otherwise, excellent post and changes! I've had very similar setup using amix/vimrc for a long time now. It looks like you already add gotags to the configuration too.

@drbig
Copy link

drbig commented Jun 17, 2014

Thank you for doing the work. Easily incorporated what I found useful (and not only for Go).

@gatspy
Copy link

gatspy commented Aug 25, 2015

Perfect.By the way, what theme you are using in screenshot.

@Lhy19
Copy link

Lhy19 commented May 8, 2016

Stupid question, but how do you get it to split like in the screenshot?

@chenruichou
Copy link

nice ide setup

@vgangireddyin
Copy link

for Ubuntu users, you may need to run sudo apt-get install ctags

@marhar
Copy link

marhar commented Sep 11, 2016

Can you put in a link to your fork of the .vimrc?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment