enable linter using nvim-lint #2956
Replies: 3 comments 1 reply
-
This sounds like a question to ask in the nvim-lint repository since it doesn't really have to do with Since I assume this tool just invokes the |
Beta Was this translation helpful? Give feedback.
-
OK so this is what I have at the moment, which doesn't work very well. 😞 Here is my # https://github.com/golangci/golangci-lint/blob/master/.golangci.reference.yml
# https://golangci-lint.run/usage/linters/#enabled-by-default-linters
linters:
enable:
- deadcode
- errcheck
- gosimple
- gofumpt
- goimports
- govet
- ineffassign
- revive
- staticcheck
- structcheck
- typecheck
- unused
- varcheck Here is an example code file that has some issues: package main
// NOTICE I'm using the io/os/fmt packages but I don't import them.
// This is to test whether goimports is being executed when I save/update this file.
// Foo is an unused constant (varcheck where are you?)
const Foo = "not used"
// Bar is an unused variable (varcheck where are you?)
var Bar = "not used"
// NOTE: all the code inside the main function is incorrectly indented, but updating the file doesn't cause gofumpt to be executed, which should fix the issue.
func main() {
fmt.Println(os.ErrClosed)
fmt.Println(io.ErrClosedPipe)
// Here is a very long line which I expect revive to complain about because it's going to be longer than 80 columns in length.
// I also think gofumpt would reformat this over multiple lines for me.
} From what I can tell the fundamental problems are gofumpt and goimports aren't running when expected. The io/os packages did eventually get dynamically added as imports when I typed os.ErrClosed and io.ErrClosedPipe. But for some reason the fmt package would not get added at all no matter how many times I typed a line consisting of that package. This suggests the goimports tool isn't always being run when it should (e.g. when the file is being written to/updated). I also noticed that when imports are dynamically added, then the order of the imports were also being sorted correctly (again, that's a side effect of goimports actually being run but just something I wanted to note). So why does typing any kind of fmt line, like Here is my neovim configuration: lua <<EOF
-- https://github.com/mfussenegger/nvim-lint#custom-linters
local lint = require('lint')
lint.linters.cargo = {
cmd = 'cargo check',
stdin = true,
args = {},
stream = 'both',
ignore_exitcode = false,
env = nil,
}
lint.linters_by_ft = {
go = {'golangcilint', 'revive'},
rust = {'cargo'},
}
local golangcilint = require("lint.linters.golangcilint")
golangcilint.append_fname = true
golangcilint.args = {
'run',
'--out-format',
'json',
}
EOF
autocmd BufWritePre <buffer> lua require('lint').try_lint()
Here is the output of manually running the $ golangci-lint run --out-format json --verbose
INFO [config_reader] Config search paths: [./ /Users/integralist/Code/go/testing-golangcilint /Users/integralist/Code/go /Users/integralist/Code /Users/integralist /Users /]
INFO [config_reader] Used config file ../../../.golangci.yml
INFO [lintersdb] Active 13 linters: [deadcode errcheck gofumpt goimports gosimple govet ineffassign revive staticcheck structcheck typecheck unused varcheck]
INFO [loader] Go packages loading at mode 575 (types_sizes|deps|files|imports|compiled_files|exports_file|name) took 103.063542ms
INFO [runner/filename_unadjuster] Pre-built 0 adjustments in 341.208µs
INFO [linters context/goanalysis] analyzers took 1.824912ms with top 10 stages: printf: 685.874µs, ctrlflow: 515.833µs, inspect: 417.374µs, testinggoroutine: 59.083µs, lostcancel: 43.375µs, cgocall: 20.167µs, tests: 7.875µs, bools: 5.583µs, typecheck: 5.583µs, httpresponse: 5.291µs
WARN [linters context] gosimple is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649.
WARN [linters context] staticcheck is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649.
WARN [linters context] structcheck is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649.
WARN [linters context] unused is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649.
INFO [runner] Issues before processing: 104, after processing: 12
INFO [runner] Processors filtering stat (out/in): path_prettifier: 104/104, autogenerated_exclude: 104/104, exclude: 104/104, nolint: 104/104, uniq_by_line: 12/104, cgo: 104/104, max_same_issues: 12/12, source_code: 12/12, path_prefixer: 12/12, filename_unadjuster: 104/104, skip_files: 104/104, identifier_marker: 104/104, max_per_file_from_linter: 12/12, severity-rules: 12/12, sort_results: 12/12, skip_dirs: 104/104, exclude-rules: 104/104, diff: 12/12, max_from_linter: 12/12, path_shortener: 12/12
INFO [runner] processing took 7.203833ms with stages: nolint: 2.286875ms, identifier_marker: 1.642417ms, exclude-rules: 1.208833ms, source_code: 578.958µs, filename_unadjuster: 303.709µs, skip_dirs: 230.625µs, path_prettifier: 201.708µs, max_same_issues: 140.625µs, cgo: 125.416µs, autogenerated_exclude: 59.334µs, max_from_linter: 57.792µs, uniq_by_line: 55.125µs, path_shortener: 51.791µs, max_per_file_from_linter: 48.333µs, diff: 47.583µs, exclude: 42.292µs, severity-rules: 40.5µs, sort_results: 33.167µs, skip_files: 29.208µs, path_prefixer: 19.542µs
INFO [runner] linters took 940.738916ms with stages: goanalysis_metalinter: 932.741458ms, gosimple: 130.333µs, unused: 27.208µs, staticcheck: 5.5µs, structcheck: 3.583µs {
"Issues": [
{
"FromLinter": "typecheck",
"Text": "undeclared name: `fmt`",
"Severity": "",
"SourceLines": [
" fmt.Println(os.ErrClosed) // but the fmt package wasn't added to import list?"
],
"Replacement": null,
"Pos": {
"Filename": "main.go",
"Offset": 0,
"Line": 15,
"Column": 3
},
"ExpectNoLint": false,
"ExpectedNoLintLinter": ""
},
{
"FromLinter": "typecheck",
"Text": "undeclared name: `fmt`",
"Severity": "",
"SourceLines": [
" fmt.Println(io.ErrClosedPipe)"
],
"Replacement": null,
"Pos": {
"Filename": "main.go",
"Offset": 0,
"Line": 16,
"Column": 3
},
"ExpectNoLint": false,
"ExpectedNoLintLinter": ""
},
{
"FromLinter": "typecheck",
"Text": "undeclared name: `any`",
"Severity": "",
"SourceLines": [
"\tNew: func() any {"
],
"Replacement": null,
"Pos": {
"Filename": "../../../../../usr/local/go/src/io/io.go",
"Offset": 0,
"Line": 600,
"Column": 14
},
"ExpectNoLint": false,
"ExpectedNoLintLinter": ""
},
{
"FromLinter": "typecheck",
"Text": "a.Lock undefined (type *onceError has no field or method Lock)",
"Severity": "",
"SourceLines": [
"\ta.Lock()"
],
"Replacement": null,
"Pos": {
"Filename": "../../../../../usr/local/go/src/io/pipe.go",
"Offset": 0,
"Line": 22,
"Column": 4
},
"ExpectNoLint": false,
"ExpectedNoLintLinter": ""
},
{
"FromLinter": "typecheck",
"Text": "a.Unlock undefined (type *onceError has no field or method Unlock)",
"Severity": "",
"SourceLines": [
"\tdefer a.Unlock()"
],
"Replacement": null,
"Pos": {
"Filename": "../../../../../usr/local/go/src/io/pipe.go",
"Offset": 0,
"Line": 23,
"Column": 10
},
"ExpectNoLint": false,
"ExpectedNoLintLinter": ""
},
{
"FromLinter": "typecheck",
"Text": "a.Lock undefined (type *onceError has no field or method Lock)",
"Severity": "",
"SourceLines": [
"\ta.Lock()"
],
"Replacement": null,
"Pos": {
"Filename": "../../../../../usr/local/go/src/io/pipe.go",
"Offset": 0,
"Line": 30,
"Column": 4
},
"ExpectNoLint": false,
"ExpectedNoLintLinter": ""
},
{
"FromLinter": "typecheck",
"Text": "a.Unlock undefined (type *onceError has no field or method Unlock)",
"Severity": "",
"SourceLines": [
"\tdefer a.Unlock()"
],
"Replacement": null,
"Pos": {
"Filename": "../../../../../usr/local/go/src/io/pipe.go",
"Offset": 0,
"Line": 31,
"Column": 10
},
"ExpectNoLint": false,
"ExpectedNoLintLinter": ""
},
{
"FromLinter": "typecheck",
"Text": "i declared but not used",
"Severity": "",
"SourceLines": [
"\t\tfor i := range iovecs {"
],
"Replacement": null,
"Pos": {
"Filename": "../../../../../usr/local/go/src/internal/poll/writev.go",
"Offset": 0,
"Line": 67,
"Column": 7
},
"ExpectNoLint": false,
"ExpectedNoLintLinter": ""
},
{
"FromLinter": "typecheck",
"Text": "m.Lock undefined (type *mmapper has no field or method Lock)",
"Severity": "",
"SourceLines": [
"\tm.Lock()"
],
"Replacement": null,
"Pos": {
"Filename": "../../../../../usr/local/go/src/syscall/syscall_unix.go",
"Offset": 0,
"Line": 74,
"Column": 4
},
"ExpectNoLint": false,
"ExpectedNoLintLinter": ""
},
{
"FromLinter": "typecheck",
"Text": "m.Unlock undefined (type *mmapper has no field or method Unlock)",
"Severity": "",
"SourceLines": [
"\tdefer m.Unlock()"
],
"Replacement": null,
"Pos": {
"Filename": "../../../../../usr/local/go/src/syscall/syscall_unix.go",
"Offset": 0,
"Line": 75,
"Column": 10
},
"ExpectNoLint": false,
"ExpectedNoLintLinter": ""
},
{
"FromLinter": "typecheck",
"Text": "m.Lock undefined (type *mmapper has no field or method Lock)",
"Severity": "",
"SourceLines": [
"\tm.Lock()"
],
"Replacement": null,
"Pos": {
"Filename": "../../../../../usr/local/go/src/syscall/syscall_unix.go",
"Offset": 0,
"Line": 87,
"Column": 4
},
"ExpectNoLint": false,
"ExpectedNoLintLinter": ""
},
{
"FromLinter": "typecheck",
"Text": "m.Unlock undefined (type *mmapper has no field or method Unlock)",
"Severity": "",
INFO File cache stats: 5 entries of total size 38.8KiB
"SourceLines": [
"\tdefer m.Unlock()"
],
"Replacement": null,
"Pos": {
"Filename": "../../../../../usr/local/go/src/syscall/syscall_unix.go",
"Offset": 0,
"Line": 88,
"Column": 10
},
"ExpectNoLint": false,
"ExpectedNoLintLinter": ""
}
],
"Report": {
"Warnings": [
{
"Tag": "linters context",
"Text": "gosimple is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
},
{
"Tag": "linters context",
"Text": "staticcheck is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
},
{
"Tag": "linters context",
"Text": "structcheck is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
},
{
"Tag": "linters context",
"Text": "unused is disabled because of go1.18. You can track the evolution of the go1.18 support by following the https://github.com/golangci/golangci-lint/issues/2649."
}
],
"Linters": [
{
"Name": "asciicheck"
},
{
"Name": "bidichk"
INFO Memory: 12 samples, avg is 117.2MB, max is 139.6MB
},
{
"Name": "bodyclose"
},
{
"Name": "containedctx"
INFO Execution took 1.064127708s
},
{
"Name": "contextcheck"
},
{
"Name": "cyclop"
},
{
"Name": "decorder"
},
{
"Name": "deadcode",
"Enabled": true,
"EnabledByDefault": true
},
{
"Name": "depguard"
},
{
"Name": "dogsled"
},
{
"Name": "dupl"
},
{
"Name": "durationcheck"
},
{
"Name": "errcheck",
"Enabled": true,
"EnabledByDefault": true
},
{
"Name": "errchkjson"
},
{
"Name": "errname"
},
{
"Name": "errorlint"
},
{
"Name": "exhaustive"
},
{
"Name": "exhaustivestruct"
},
{
"Name": "exportloopref"
},
{
"Name": "forbidigo"
},
{
"Name": "forcetypeassert"
},
{
"Name": "funlen"
},
{
"Name": "gci"
},
{
"Name": "gochecknoglobals"
},
{
"Name": "gochecknoinits"
},
{
"Name": "gocognit"
},
{
"Name": "goconst"
},
{
"Name": "gocritic"
},
{
"Name": "gocyclo"
},
{
"Name": "godot"
},
{
"Name": "godox"
},
{
"Name": "goerr113"
},
{
"Name": "gofmt"
},
{
"Name": "gofumpt",
"Enabled": true
},
{
"Name": "goheader"
},
{
"Name": "goimports",
"Enabled": true
},
{
"Name": "golint"
},
{
"Name": "gomnd"
},
{
"Name": "gomoddirectives"
},
{
"Name": "gomodguard"
},
{
"Name": "goprintffuncname"
},
{
"Name": "gosec"
},
{
"Name": "gosimple",
"Enabled": true,
"EnabledByDefault": true
},
{
"Name": "govet",
"Enabled": true,
"EnabledByDefault": true
},
{
"Name": "grouper"
},
{
"Name": "ifshort"
},
{
"Name": "importas"
},
{
"Name": "ineffassign",
"Enabled": true,
"EnabledByDefault": true
},
{
"Name": "interfacer"
},
{
"Name": "ireturn"
},
{
"Name": "lll"
},
{
"Name": "maintidx"
},
{
"Name": "makezero"
},
{
"Name": "maligned"
},
{
"Name": "misspell"
},
{
"Name": "nakedret"
},
{
"Name": "nestif"
},
{
"Name": "nilerr"
},
{
"Name": "nilnil"
},
{
"Name": "nlreturn"
},
{
"Name": "noctx"
},
{
"Name": "paralleltest"
},
{
"Name": "prealloc"
},
{
"Name": "predeclared"
},
{
"Name": "promlinter"
},
{
"Name": "revive",
"Enabled": true
},
{
"Name": "rowserrcheck"
},
{
"Name": "scopelint"
},
{
"Name": "sqlclosecheck"
},
{
"Name": "staticcheck",
"Enabled": true,
"EnabledByDefault": true
},
{
"Name": "structcheck",
"Enabled": true,
"EnabledByDefault": true
},
{
"Name": "stylecheck"
},
{
"Name": "tagliatelle"
},
{
"Name": "tenv"
},
{
"Name": "testpackage"
},
{
"Name": "thelper"
},
{
"Name": "tparallel"
},
{
"Name": "typecheck",
"Enabled": true,
"EnabledByDefault": true
},
{
"Name": "unconvert"
},
{
"Name": "unparam"
},
{
"Name": "unused",
"Enabled": true,
"EnabledByDefault": true
},
{
"Name": "varcheck",
"Enabled": true,
"EnabledByDefault": true
},
{
"Name": "varnamelen"
},
{
"Name": "wastedassign"
},
{
"Name": "whitespace"
},
{
"Name": "wrapcheck"
},
{
"Name": "wsl"
},
{
"Name": "nolintlint"
}
]
}
} Other neovim configuration I have is (this was placed after the above neovim configuration in my lua <<EOF
require('lspconfig').gopls.setup{
cmd = {'gopls'},
settings = {
gopls = {
analyses = {
nilness = true,
unusedparams = true,
unusedwrite = true,
useany = true,
},
experimentalPostfixCompletions = true,
gofumpt = true,
staticcheck = true,
usePlaceholders = true,
},
},
}
EOF |
Beta Was this translation helpful? Give feedback.
-
I've also just tried with a fresh project: package main
func main() {
fmt.Println("hello world")
} The
Again this suggests the But then I went to check for a code action on the
Once I selected one of the options, and the package was imported for me, the error disappeared obviously, but then I saw the following error:
|
Beta Was this translation helpful? Give feedback.
-
I'm trying to use https://github.com/mfussenegger/nvim-lint to run golangci-lint but the
gofumpt
command isn't enabled by default.The nvim-lint repo has a way to customise a linting tool like golangci-lint but I'm not sure how to configure the specific
--enable
flag which is under theconfig path
command (which I think is what I need to do)?Beta Was this translation helpful? Give feedback.
All reactions