Skip to content

Commit e37e1f1

Browse files
committed
lint: make gopls diagnostics visible
Add a new comamnd, `:GoDiagnostics`, to display the LSP diagnostics for packages. Teach :GoMetaLinter to display LSP diagnostics when g:go_metalinter_command == 'gopls'. Closes fatih#2538
1 parent eca8bb0 commit e37e1f1

File tree

8 files changed

+335
-70
lines changed

8 files changed

+335
-70
lines changed

autoload/go/lint.vim

+79-12
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ function! go#lint#Gometa(bang, autosave, ...) abort
1111

1212
let l:metalinter = go#config#MetalinterCommand()
1313

14+
let cmd = []
1415
if l:metalinter == 'golangci-lint'
1516
let cmd = s:metalintercmd(l:metalinter)
1617
if empty(cmd)
@@ -22,7 +23,7 @@ function! go#lint#Gometa(bang, autosave, ...) abort
2223
for linter in linters
2324
let cmd += ["--enable=".linter]
2425
endfor
25-
else
26+
elseif l:metalinter != 'gopls'
2627
" the user wants something else, let us use it.
2728
let cmd = split(go#config#MetalinterCommand(), " ")
2829
endif
@@ -45,17 +46,35 @@ function! go#lint#Gometa(bang, autosave, ...) abort
4546

4647
let cmd += goargs
4748

48-
" Golangci-lint can output the following:
49-
" <file>:<line>:<column>: <message> (<linter>)
50-
" This can be defined by the following errorformat:
51-
let errformat = "%f:%l:%c:\ %m"
49+
let errformat = s:errorformat(l:metalinter)
5250

53-
if go#util#has_job()
54-
call s:lint_job({'cmd': cmd, 'statustype': l:metalinter, 'errformat': errformat}, a:bang, a:autosave)
55-
return
56-
endif
51+
if l:metalinter == 'gopls'
52+
if a:autosave
53+
let l:messages = go#lsp#AnalyzeFile(expand('%:p'))
54+
else
55+
let l:import_paths = l:goargs
56+
if len(l:import_paths) == 0
57+
let l:pkg = go#package#ImportPath()
58+
if l:pkg == -1
59+
call go#util#EchoError('could not determine package name')
60+
return
61+
endif
62+
63+
let l:import_paths = [l:pkg]
64+
endif
65+
let l:messages = call('go#lsp#Diagnostics', l:import_paths)
66+
endif
67+
68+
let l:err = len(l:messages)
69+
else
70+
if go#util#has_job()
71+
call s:lint_job({'cmd': cmd, 'statustype': l:metalinter, 'errformat': errformat}, a:bang, a:autosave)
72+
return
73+
endif
5774

58-
let [l:out, l:err] = go#util#Exec(cmd)
75+
let [l:out, l:err] = go#util#Exec(cmd)
76+
let l:messages = split(out, "\n")
77+
endif
5978

6079
if a:autosave
6180
let l:listtype = go#list#Type("GoMetaLinterAutoSave")
@@ -70,8 +89,6 @@ function! go#lint#Gometa(bang, autosave, ...) abort
7089
let l:winid = win_getid(winnr())
7190
" Parse and populate our location list
7291

73-
let l:messages = split(out, "\n")
74-
7592
if a:autosave
7693
call s:metalinterautosavecomplete(fnamemodify(expand('%:p'), ":."), 0, 1, l:messages)
7794
endif
@@ -88,6 +105,44 @@ function! go#lint#Gometa(bang, autosave, ...) abort
88105
endif
89106
endfunction
90107

108+
function! go#lint#Diagnostics(bang, ...) abort
109+
if a:0 == 0
110+
let l:pkg = go#package#ImportPath()
111+
if l:pkg == -1
112+
call go#util#EchoError('could not determine package name')
113+
return
114+
endif
115+
116+
let l:import_paths = [l:pkg]
117+
else
118+
let l:import_paths = a:000
119+
endif
120+
121+
let errformat = s:errorformat('gopls')
122+
123+
let l:messages = call('go#lsp#Diagnostics', l:import_paths)
124+
125+
let l:listtype = go#list#Type("GoDiagnostics")
126+
127+
if len(l:messages) == 0
128+
call go#list#Clean(l:listtype)
129+
call go#util#EchoSuccess('[diagnostics] PASS')
130+
else
131+
" Parse and populate the quickfix list
132+
let l:winid = win_getid(winnr())
133+
call go#list#ParseFormat(l:listtype, errformat, l:messages, 'GoDiagnostics')
134+
135+
let errors = go#list#Get(l:listtype)
136+
call go#list#Window(l:listtype, len(errors))
137+
138+
if a:bang
139+
call win_gotoid(l:winid)
140+
return
141+
endif
142+
call go#list#JumpToFirst(l:listtype)
143+
endif
144+
endfunction
145+
91146
" Golint calls 'golint' on the current directory. Any warnings are populated in
92147
" the location list
93148
function! go#lint#Golint(bang, ...) abort
@@ -272,6 +327,18 @@ function! s:metalinterautosavecomplete(filepath, job, exit_code, messages)
272327
endwhile
273328
endfunction
274329

330+
function! s:errorformat(metalinter) abort
331+
if a:metalinter == 'golangci-lint'
332+
" Golangci-lint can output the following:
333+
" <file>:<line>:<column>: <message> (<linter>)
334+
" This can be defined by the following errorformat:
335+
return '%f:%l:%c:\ %m'
336+
elseif a:metalinter == 'gopls'
337+
return '%f:%l:%c:%t:\ %m,%f:%l:%c::\ %m'
338+
endif
339+
340+
endfunction
341+
275342
" restore Vi compatibility settings
276343
let &cpo = s:cpo_save
277344
unlet s:cpo_save

autoload/go/list.vim

+1
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ endfunction
135135
" in g:go_list_type_commands.
136136
let s:default_list_type_commands = {
137137
\ "GoBuild": "quickfix",
138+
\ "GoDiagnostics": "quickfix",
138139
\ "GoDebug": "quickfix",
139140
\ "GoErrCheck": "quickfix",
140141
\ "GoFmt": "locationlist",

0 commit comments

Comments
 (0)