Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gometalinter integration #553

Merged
merged 11 commits into from
Sep 30, 2015
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ disabled/enabled easily.
* Change or display `GOPATH` with `:GoPath`
* Create a coverage profile and display annotated source code in browser to see
which functions are covered with `:GoCoverage`
* Call `gometalinter`, which is a tool that invokes all possible linters
(golint, vet, errcheck, deadcode, etc..) and shows the warnings/errors
* Lint your code with `:GoLint`
* Run your code through `:GoVet` to catch static errors
* Advanced source analysis tools utilizing oracle, such as `:GoImplements`,
Expand Down
27 changes: 0 additions & 27 deletions autoload/go/cmd.vim
Original file line number Diff line number Diff line change
Expand Up @@ -216,32 +216,6 @@ function! go#cmd#Coverage(bang, ...)
call delete(l:tmpname)
endfunction

" Vet calls "go vet' on the current directory. Any warnings are populated in
" the quickfix window
function! go#cmd#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
call go#tool#ShowErrors(out)
else
call setqflist([])
endif

let errors = getqflist()
if !empty(errors)
if !a:bang
cc 1 "jump to first error if there is any
endif
else
redraw | echon "vim-go: " | echohl Function | echon "[vet] PASS" | echohl None
endif
endfunction
"
" Generate runs 'go generate' in similar fashion to go#cmd#Build()
function! go#cmd#Generate(bang, ...)
let default_makeprg = &makeprg
Expand Down Expand Up @@ -281,4 +255,3 @@ function! go#cmd#Generate(bang, ...)
endfunction

" vim:ts=4:sw=4:et
"
58 changes: 0 additions & 58 deletions autoload/go/errcheck.vim

This file was deleted.

172 changes: 157 additions & 15 deletions autoload/go/lint.vim
Original file line number Diff line number Diff line change
@@ -1,22 +1,83 @@
" Copyright 2013 The Go Authors. All rights reserved.
" Use of this source code is governed by a BSD-style
" license that can be found in the LICENSE file.
"
" lint.vim: Vim command to lint Go files with golint.
"
" https://github.com/golang/lint
"
" This filetype plugin add a new commands for go buffers:
"
" :GoLint [options]
"
" Run golint for the current Go file.
"
if !exists("g:go_metalinter_command")
let g:go_metalinter_command = ""
endif

if !exists("g:go_metalinter_enabled")
let g:go_metalinter_enabled = ['vet', 'golint', 'errcheck']
endif

if !exists("g:go_metalinter_path")
let g:go_metalinter_path = "./..."
endif

if !exists("g:go_golint_bin")
let g:go_golint_bin = "golint"
endif

function! go#lint#Run(...) abort
if !exists("g:go_errcheck_bin")
let g:go_errcheck_bin = "errcheck"
endif

function! go#lint#Gometa(path_to_lint) abort
let meta_command = "gometalinter --disable-all"
if empty(g:go_metalinter_command)
let bin_path = go#path#CheckBinPath("gometalinter")
if empty(bin_path)
return
endif

if empty(g:go_metalinter_enabled)
echohl Error | echomsg "vim-go: please enable linters with the setting g:go_metalinter_enabled" | echohl None
return
endif

for linter in g:go_metalinter_enabled
let meta_command .= " --enable=".linter
endfor


" by default we search for all underlying files
let path = g:go_metalinter_path
if !empty(a:path_to_lint)
let path = a:path_to_lint
endif

let meta_command .= path
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 setqflist([])
echon "vim-go: " | echohl Function | echon "[metalinter] PASS" | echohl None
else
" backup users errorformat, will be restored once we are finished
let old_errorformat = &errorformat

" GoMetaLinter can output one of the two, so we look for both of them
" <file>:<line>:[<column>]: <message> (<linter>)
" <file>:<line>:: <message> (<linter>)
let &errorformat = "%f:%l:%c:%t%*[^:]:\ %m,%f:%l::%t%*[^:]:\ %m"

" create the quickfix list and open it
cgetexpr split(out, "\n")
cwindow

let &errorformat = old_errorformat
endif
endfunction

" Golint calls 'golint' on the current directory. Any warnings are populated in
" the quickfix window
function! go#lint#Golint(...) abort
let bin_path = go#path#CheckBinPath(g:go_golint_bin)
if empty(bin_path)
return
Expand All @@ -31,5 +92,86 @@ function! go#lint#Run(...) abort
cwindow
endfunction

" Vet calls 'go vet' on the current directory. Any warnings are populated in
" the quickfix window
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
call go#tool#ShowErrors(out)
else
call setqflist([])
endif

cwindow
let errors = getqflist()
if !empty(errors)
if !a:bang
cc 1 "jump to first error if there is any
endif
else
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 quickfix window.
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
endif

if !empty(errors)
redraw | echo
call setqflist(errors, 'r')
endif
else
redraw | echo
call setqflist([])
echon "vim-go: " | echohl Function | echon "[errcheck] PASS" | echohl None
endif

cwindow
endfunction

" vim:ts=4:sw=4:et
38 changes: 38 additions & 0 deletions doc/vim-go.txt
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,17 @@ COMMANDS *go-commands*
object as does the selected identifier, within any package in the analysis
scope.

*:GoMetaLinter*
:GoMetaLinter [path]

Calls the underlying `gometalinter` tool and displays all warnings and
errors in a quickfix window. By default it lints the files for the path
`./...` . This can be changed with the 'path' argument temoporary or with the
|g:go_metalinter_path| variable permanently. By default the following
linters are enabled: "'vet', 'golint', 'errcheck'". This can be changed
with the |g:go_metalinter_enabled| variable. To override the command
completely use the variable |g:go_metalinter_command|


===============================================================================
MAPPINGS *go-mappings*
Expand Down Expand Up @@ -565,6 +576,9 @@ Show send/receive corresponding to selected channel op

Show all refs to entity denoted by selected identifier

*(go-metalinter)*

Calls `go-metalinter` for the current directory

===============================================================================
TEXT OBJECTS *go-text-objects*
Expand Down Expand Up @@ -817,7 +831,31 @@ supports will be added. By default it's enabled. >
Adds custom text objects. By default it's enabled. >

let g:go_textobj_enabled = 1
<

*'g:go_metalinter_enabled'*

Specifies the currently enabled linters for the |GoMetaLinter| command. By
default it's using `vet`, `golint` and `errcheck`
>
let g:go_metalinter_enabled = ['vet', 'golint', 'errcheck']
<
*'g:go_metalinter_command'*

Overrides the command to be executed when |GoMetaLinter| is called. This is
an advanced settings and is for users who want to have a complete control
over of how `gometalinter` should be executed. By default it's empty.
>
let g:go_metalinter_command = ""
<
*'g:go_metalinter_path'*

Defines the default path to be linted for the |GoMetaLinter| command. By
default it's set to `./...`, which recursively lints all files underd the
current directory.
>
let g:go_metalinter_path = "./..."
<

===============================================================================
TROUBLESHOOTING *go-troubleshooting*
Expand Down
Loading