ascent.io

random musings and unkept thoughts

Run Fmt Upon Save in Vim

| Comments

I’ve been working with Go for a few weeks now and thought I had vim set up to format my code using Fmt every time I saved. I did and I didn’t.

You see, we are working on the authorization piece of Ottemo and since many projects can benefit from the work we are doing, we wanted to submit our OAUTH2 work to the Martini project.

And, as should be, the source code needed to be formatted according to Golang standards.

The one liner, which will format your code is below:

.vimrc
1
2
" format golang upon save
autocmd FileType go autocmd BufWritePre <buffer> Fmt

However, there is a little more to the puzzle. In most cases I prefer spaces to tabs, but this is not a discussion on tabs vs. spaces. Somehow this formatting was not being set upon save. No matter what I did, it still saved the file replacing tabs with spaces and an indention of 2 spaces.

I quickly found the culprit. In my .vimrc I have my default settings for managing tabs and spaces to default to 2 spaces and to convert tabs to spaces when I save a file.

1
2
3
4
5
set tabstop=2             " number of spaces that a <tab> represents in a file
set shiftwidth=2          " number of spaces to use for (auto)indent
set expandtab             " expand tabs to spaces
set softtabstop=2         " number of spaces that a <tab> represents
set smarttab              " smart handling of tabs when inserting or deleting

This meant that when I opened a Golang formatted file, as soon as I saved it, gone were the tabs in my Golang files. I wanted to adhere to the standard, so I needed to find a way to make an exception for Go source files. According to the Go formatting standards they use tabs with a tabstop of 8.

To make an exception for Go source code, I am using the setlocal identifier to apply the exception to my global settings. Here is the result:

1
2
autocmd FileType go setlocal shiftwidth=8 tabstop=8 softtabstop=8     " set tab stops to 8 for Go files
autocmd FileType go setlocal noexpandtab                              " don't expand tabs to spaces for Go files

This fixed my problems when saving Go formatted files and saves me from running go Fmt on my files outside of vim.

Here is my final set of vim customizations:

.vimrc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
" Go tagbar config
let g:tagbar_type_go = {
    \ 'ctagstype' : 'go',
    \ 'kinds'     : [
        \ 'p:package',
        \ 'i:imports:1',
        \ 'c:constants',
        \ 'v:variables',
        \ 't:types',
        \ 'n:interfaces',
        \ 'w:fields',
        \ 'e:embedded',
        \ 'm:methods',
        \ 'r:constructor',
        \ 'f:functions'
    \ ],
    \ 'sro' : '.',
    \ 'kind2scope' : {
        \ 't' : 'ctype',
        \ 'n' : 'ntype'
    \ },
    \ 'scope2kind' : {
        \ 'ctype' : 't',
        \ 'ntype' : 'n'
    \ },
    \ 'ctagsbin'  : 'gotags',
    \ 'ctagsargs' : '-sort -silent'
\ }

" Golang customizations
"
" generate go ctags upon save
au BufWritePost *.go silent! !ctags -R --exclude=*.js,*.html &
autocmd FileType go autocmd BufWritePre <buffer> Fmt                  " format files upon save in GO
let g:syntastic_go_checkers = ['go','golint']                         " use golint for syntax checking in Go
let g:godef_same_file_in_same_window=1                                " when in go, move the cursor if in same file 
autocmd FileType go setlocal shiftwidth=8 tabstop=8 softtabstop=8     " set tab stops to 8 for Go files
autocmd FileType go setlocal noexpandtab                              " don't expand tabs to spaces for Go files

If you see any issues with my customizations or think I should do something differently, let me know.

Cheers

Comments