@@ -11,6 +11,7 @@ function! go#lint#Gometa(bang, autosave, ...) abort
11
11
12
12
let l: metalinter = go#config#MetalinterCommand ()
13
13
14
+ let cmd = []
14
15
if l: metalinter == ' golangci-lint'
15
16
let cmd = s: metalintercmd (l: metalinter )
16
17
if empty (cmd)
@@ -22,7 +23,7 @@ function! go#lint#Gometa(bang, autosave, ...) abort
22
23
for linter in linters
23
24
let cmd += [" --enable=" .linter]
24
25
endfor
25
- else
26
+ elseif l: metalinter != ' gopls '
26
27
" the user wants something else, let us use it.
27
28
let cmd = split (go#config#MetalinterCommand (), " " )
28
29
endif
@@ -45,17 +46,35 @@ function! go#lint#Gometa(bang, autosave, ...) abort
45
46
46
47
let cmd += goargs
47
48
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 )
52
50
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
57
74
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
59
78
60
79
if a: autosave
61
80
let l: listtype = go#list#Type (" GoMetaLinterAutoSave" )
@@ -70,9 +89,7 @@ function! go#lint#Gometa(bang, autosave, ...) abort
70
89
let l: winid = win_getid (winnr ())
71
90
" Parse and populate our location list
72
91
73
- let l: messages = split (out, " \n " )
74
-
75
- if a: autosave
92
+ if a: autosave && l: metalinter != ' gopls'
76
93
call s: metalinterautosavecomplete (fnamemodify (expand (' %:p' ), " :." ), 0 , 1 , l: messages )
77
94
endif
78
95
call go#list#ParseFormat (l: listtype , errformat, l: messages , ' GoMetaLinter' )
@@ -88,6 +105,44 @@ function! go#lint#Gometa(bang, autosave, ...) abort
88
105
endif
89
106
endfunction
90
107
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
+
91
146
" Golint calls 'golint' on the current directory. Any warnings are populated in
92
147
" the location list
93
148
function ! go#lint#Golint (bang , ... ) abort
@@ -275,18 +330,25 @@ function! s:metalinterautosavecomplete(filepath, job, exit_code, messages)
275
330
276
331
let l: idx = len (a: messages ) - 1
277
332
while l: idx >= 0
278
- " Go 1.13 changed how go vet output is formatted by prepending a leading
279
- " 'vet :', so account for that, too. This function is really needed for
280
- " gometalinter at all, so the check for Go 1.13's go vet output shouldn't
281
- " be neeeded, but s:lint_job hooks this up even when the
282
- " g:go_metalinter_command is golangci-lint.
283
- if a: messages [l: idx ] !~# ' ^' . a: filepath . ' :' && a: messages [l: idx ] !~# ' ^vet: \.[\\/]' . a: filepath . ' :'
333
+ if a: messages [l: idx ] !~# ' ^' . a: filepath . ' :'
284
334
call remove (a: messages , l: idx )
285
335
endif
286
336
let l: idx -= 1
287
337
endwhile
288
338
endfunction
289
339
340
+ function ! s: errorformat (metalinter) abort
341
+ if a: metalinter == ' golangci-lint'
342
+ " Golangci-lint can output the following:
343
+ " <file>:<line>:<column>: <message> (<linter>)
344
+ " This can be defined by the following errorformat:
345
+ return ' %f:%l:%c:\ %m'
346
+ elseif a: metalinter == ' gopls'
347
+ return ' %f:%l:%c:%t:\ %m,%f:%l:%c::\ %m'
348
+ endif
349
+
350
+ endfunction
351
+
290
352
" restore Vi compatibility settings
291
353
let &cpo = s: cpo_save
292
354
unlet s: cpo_save
0 commit comments