diff --git a/README.md b/README.md index e75c3271a8..6b96d3abd5 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ disabled/enabled easily. * Share your current code to [play.golang.org](http://play.golang.org) with `:GoPlay` * On-the-fly type information about the word under the cursor. Plug it into your custom vim function. +* Go asm formatting on save * Tagbar support to show tags of the source code in a sidebar with `gotags` * Custom vim text objects such as `a function` or `inner function` * All commands support collecting and displaying errors in Vim's location diff --git a/autoload/go/asmfmt.vim b/autoload/go/asmfmt.vim new file mode 100644 index 0000000000..0b427944ec --- /dev/null +++ b/autoload/go/asmfmt.vim @@ -0,0 +1,52 @@ +" asmfmt.vim: Vim command to format Go asm files with asmfmt +" (github.com/klauspost/asmfmt). +" +" This filetype plugin adds new commands for asm buffers: +" +" :Fmt +" +" Filter the current asm buffer through asmfmt. +" It tries to preserve cursor position and avoids +" replacing the buffer with stderr output. +" +" Options: +" +" g:go_asmfmt_autosave [default=1] +" +" Flag to automatically call :Fmt when file is saved. + +let s:got_fmt_error = 0 + +" This is a trimmed-down version of the logic in fmt.vim. + +function! go#asmfmt#Format() + " Save state. + let l:curw = winsaveview() + + " Write the current buffer to a tempfile. + let l:tmpname = tempname() + call writefile(getline(1, '$'), l:tmpname) + + " Run asmfmt. + let path = go#path#CheckBinPath("asmfmt") + if empty(path) + return + endif + let out = system(path . ' -w ' . l:tmpname) + + " If there's no error, replace the current file with the output. + if v:shell_error == 0 + " Remove undo point caused by BufWritePre. + try | silent undojoin | catch | endtry + + " Replace the current file with the temp file; then reload the buffer. + let old_fileformat = &fileformat + call rename(l:tmpname, expand('%')) + silent edit! + let &fileformat = old_fileformat + let &syntax = &syntax + endif + + " Restore the cursor/window positions. + call winrestview(l:curw) +endfunction diff --git a/doc/vim-go.txt b/doc/vim-go.txt index 2786208c8d..9764968a3b 100755 --- a/doc/vim-go.txt +++ b/doc/vim-go.txt @@ -61,6 +61,7 @@ easily. * Share your current code to [play.golang.org](http://play.golang.org) with `:GoPlay` * On-the-fly type information about the word under the cursor. Plug it into your custom vim function. + * Go asm formatting on save * Tagbar support to show tags of the source code in a sidebar with `gotags` * Custom vim text objects such as `a function` or `inner function` * All commands support collecting and displaying errors in Vim's location @@ -451,6 +452,13 @@ COMMANDS *go-commands* The custom build tags is cleared (unset) if `""` is given. If no arguments is given it prints the current custom build tags. + *:AsmFmt* +:AsmFmt + + Filter the current Go asm buffer through asmfmt. It tries to preserve cursor + position and avoids replacing the buffer with stderr output. + + =============================================================================== MAPPINGS *go-mappings* @@ -908,6 +916,13 @@ up to 10 errors to prevent large heights). Setting the value explicitly overrides this behavior. To get default Vim behavior set it to 10. > let g:go_loclist_height = 0 +< + *'g:go_asmfmt_autosave'* + +Use this option to auto |:AsmFmt| on save. By default it's enabled. > + + let g:go_asmfmt_autosave = 1 +< =============================================================================== TROUBLESHOOTING *go-troubleshooting* diff --git a/ftdetect/gofiletype.vim b/ftdetect/gofiletype.vim index 573dbb01e7..b5578a6e59 100644 --- a/ftdetect/gofiletype.vim +++ b/ftdetect/gofiletype.vim @@ -5,11 +5,11 @@ let s:current_fileformats = '' let s:current_fileencodings = '' " define fileencodings to open as utf-8 encoding even if it's ascii. -function! s:gofiletype_pre() +function! s:gofiletype_pre(type) let s:current_fileformats = &g:fileformats let s:current_fileencodings = &g:fileencodings set fileencodings=utf-8 fileformats=unix - setlocal filetype=go + let &l:filetype = a:type endfunction " restore fileencodings as others @@ -19,9 +19,13 @@ function! s:gofiletype_post() endfunction au BufNewFile *.go setfiletype go | setlocal fileencoding=utf-8 fileformat=unix -au BufRead *.go call s:gofiletype_pre() +au BufRead *.go call s:gofiletype_pre("go") au BufReadPost *.go call s:gofiletype_post() +au BufNewFile *.s setfiletype asm | setlocal fileencoding=utf-8 fileformat=unix +au BufRead *.s call s:gofiletype_pre("asm") +au BufReadPost *.s call s:gofiletype_post() + au BufRead,BufNewFile *.tmpl set filetype=gohtmltmpl " vim:ts=4:sw=4:et diff --git a/ftplugin/asm.vim b/ftplugin/asm.vim new file mode 100644 index 0000000000..0ac3594bf1 --- /dev/null +++ b/ftplugin/asm.vim @@ -0,0 +1,17 @@ +" asm.vim: Vim filetype plugin for Go assembler. + +if exists("b:did_ftplugin") + finish +endif +let b:did_ftplugin = 1 + +let b:undo_ftplugin = "setl fo< com< cms<" + +setlocal formatoptions-=t + +setlocal comments=s1:/*,mb:*,ex:*/,:// +setlocal commentstring=//\ %s + +setlocal noexpandtab + +command! -nargs=0 AsmFmt call go#asmfmt#Format() diff --git a/plugin/go.vim b/plugin/go.vim index 43295ad756..88cbd4a35c 100644 --- a/plugin/go.vim +++ b/plugin/go.vim @@ -17,6 +17,7 @@ let s:packages = [ \ "github.com/golang/lint/golint", \ "github.com/kisielk/errcheck", \ "github.com/jstemmer/gotags", + \ "github.com/klauspost/asmfmt/cmd/asmfmt", \ ] " These commands are available on any filetypes @@ -128,11 +129,16 @@ augroup vim-go autocmd CursorHold *.go nested call go#complete#Info() endif - " code formatting on save + " Go code formatting on save if get(g:, "go_fmt_autosave", 1) autocmd BufWritePre *.go call go#fmt#Format(-1) endif + " Go asm formatting on save + if get(g:, "go_asmfmt_autosave", 1) + autocmd BufWritePre *.s call go#asmfmt#Format() + endif + " run gometalinter on save if get(g:, "go_metalinter_autosave", 0) autocmd BufWritePost *.go call go#lint#Gometa(1)