if !exists("g:go_metalinter_command") let g:go_metalinter_command = "" endif if !exists("g:go_metalinter_autosave_enabled") let g:go_metalinter_autosave_enabled = ['vet', 'golint'] endif if !exists("g:go_metalinter_enabled") let g:go_metalinter_enabled = ['vet', 'golint', 'errcheck'] endif if !exists("g:go_metalinter_deadline") let g:go_metalinter_deadline = "5s" endif if !exists("g:go_golint_bin") let g:go_golint_bin = "golint" endif if !exists("g:go_errcheck_bin") let g:go_errcheck_bin = "errcheck" endif function! go#lint#Gometa(autosave, ...) abort if a:0 == 0 let goargs = expand('%:p:h') else let goargs = go#util#Shelljoin(a:000) endif let meta_command = "gometalinter --disable-all" if a:autosave || empty(g:go_metalinter_command) let bin_path = go#path#CheckBinPath("gometalinter") if empty(bin_path) return endif if a:autosave " include only messages for the active buffer let meta_command .= " --include='^" . expand('%:p') . ".*$'" endif " linters let linters = a:autosave ? g:go_metalinter_autosave_enabled : g:go_metalinter_enabled for linter in linters let meta_command .= " --enable=".linter endfor " deadline let meta_command .= " --deadline=" . g:go_metalinter_deadline " path let meta_command .= " " . goargs else " the user wants something else, let us use it. let meta_command = g:go_metalinter_command endif " comment out the following two lines for debugging " echo meta_command " return let out = go#tool#ExecuteInDir(meta_command) if v:shell_error == 0 redraw | echo call go#list#Clean() call go#list#Window() echon "vim-go: " | echohl Function | echon "[metalinter] PASS" | echohl None else " GoMetaLinter can output one of the two, so we look for both: " ::[]: () " ::: () " This can be defined by the following errorformat: let errformat = "%f:%l:%c:%t%*[^:]:\ %m,%f:%l::%t%*[^:]:\ %m" " Parse and populate our location list call go#list#ParseFormat(errformat, split(out, "\n")) let errors = go#list#Get() call go#list#Window(len(errors)) if !a:autosave call go#list#JumpToFirst() endif endif endfunction " Golint calls 'golint' on the current directory. Any warnings are populated in " the location list function! go#lint#Golint(...) abort let bin_path = go#path#CheckBinPath(g:go_golint_bin) if empty(bin_path) return endif if a:0 == 0 let goargs = shellescape(expand('%')) else let goargs = go#util#Shelljoin(a:000) endif let out = system(bin_path . " " . goargs) if empty(out) echon "vim-go: " | echohl Function | echon "[lint] PASS" | echohl None return endif call go#list#Parse(out) let errors = go#list#Get() call go#list#Window(len(errors)) call go#list#JumpToFirst() endfunction " Vet calls 'go vet' on the current directory. Any warnings are populated in " the location list function! go#lint#Vet(bang, ...) call go#cmd#autowrite() echon "vim-go: " | echohl Identifier | echon "calling vet..." | echohl None if a:0 == 0 let out = go#tool#ExecuteInDir('go vet') else let out = go#tool#ExecuteInDir('go tool vet ' . go#util#Shelljoin(a:000)) endif if v:shell_error let errors = go#tool#ParseErrors(split(out, '\n')) call go#list#Populate(errors) call go#list#Window(len(errors)) if !empty(errors) && !a:bang call go#list#JumpToFirst() endif echon "vim-go: " | echohl ErrorMsg | echon "[vet] FAIL" | echohl None else call go#list#Clean() call go#list#Window() redraw | echon "vim-go: " | echohl Function | echon "[vet] PASS" | echohl None endif endfunction " ErrCheck calls 'errcheck' for the given packages. Any warnings are populated in " the location list function! go#lint#Errcheck(...) abort if a:0 == 0 let goargs = go#package#ImportPath(expand('%:p:h')) if goargs == -1 echohl Error | echomsg "vim-go: package is not inside GOPATH src" | echohl None return endif else let goargs = go#util#Shelljoin(a:000) endif let bin_path = go#path#CheckBinPath(g:go_errcheck_bin) if empty(bin_path) return endif echon "vim-go: " | echohl Identifier | echon "errcheck analysing ..." | echohl None redraw let command = bin_path . ' ' . goargs let out = go#tool#ExecuteInDir(command) if v:shell_error let errors = [] let mx = '^\(.\{-}\):\(\d\+\):\(\d\+\)\s*\(.*\)' for line in split(out, '\n') let tokens = matchlist(line, mx) if !empty(tokens) call add(errors, {"filename": expand(go#path#Default() . "/src/" . tokens[1]), \"lnum": tokens[2], \"col": tokens[3], \"text": tokens[4]}) endif endfor if empty(errors) echohl Error | echomsg "GoErrCheck returned error" | echohl None echo out return endif if !empty(errors) call go#list#Populate(errors) call go#list#Window(len(errors)) if !empty(errors) call go#list#JumpToFirst() endif endif else call go#list#Clean() call go#list#Window() echon "vim-go: " | echohl Function | echon "[errcheck] PASS" | echohl None endif endfunction " vim:ts=4:sw=4:et