Overview
nvim-lint provides asynchronous linting with support for multiple linters per filetype. Unlike automatic formatting, linting is triggered manually or on specific events. Configuration file:lua/plugins/linting.lua:7
Installation
Biome linting is handled via LSP (see
lua/plugins/lsp/init.lua) and only activates when a biome.json file exists in the project.Manual linting trigger
Keymap
Keymap
Trigger linting - Manually runs linters for the current buffer’s filetypeShows notification with:
- List of linters being run (if configured)
- Warning if no linters are configured for the filetype
Linting is manual by default. Press
<leader>ll to run linters on the current file.Linter configurations
golangci-lint (Go)
golangci-lint (Go)
Special configuration for golangci-lint with custom argument handling:Arguments:
Prevents treating non-zero exit codes as errors (some linters exit with 1 when issues are found).
run- Run linter--output.json.path=stdout- Output JSON to stdout (v2 format)--output.text.path=- Disable text output--show-stats=false- Disable statistics-c=<config>- Auto-detected config file path- Working directory - Set to current file’s directory
.golangci.yaml.golangci.yml.golangci.toml.golangci.json
$HOME.Linters by filetype
- JSON
- Go
- Shell scripts
- Docker
- YAML
- C/C++
- Markdown
- TOML
- Protocol Buffers
- JavaScript/TypeScript
Linter features
eslint_d (JavaScript/TypeScript)
eslint_d (JavaScript/TypeScript)
eslint_d is a daemon version of ESLint that provides:
- Significantly faster linting (daemon stays running)
- Automatic project root detection
- Respects
.eslintrc,.eslintrc.json,eslint.config.jsconfigurations - Works with all ESLint plugins
eslint_d automatically detects the project root by searching for ESLint config files.
shellcheck (Shell scripts)
shellcheck (Shell scripts)
shellcheck provides:
- Syntax error detection
- Semantic issues (quoting, deprecated syntax, etc.)
- Best practices suggestions
- POSIX compliance checking
- Works with sh, bash, and zsh
hadolint (Dockerfiles)
hadolint (Dockerfiles)
hadolint checks for:
- Dockerfile syntax errors
- Best practices violations
- Security issues
- Performance problems
- Deprecated instructions
golangci-lint (Go)
golangci-lint (Go)
golangci-lint runs multiple linters in parallel:
- Supports 50+ different Go linters
- Fast parallel execution
- Configurable via
.golangci.yaml - Caching for improved performance
- Auto-detects Go module root
markdownlint-cli2 (Markdown)
markdownlint-cli2 (Markdown)
markdownlint-cli2 provides:
- Markdown style consistency
- Syntax validation
- Configurable rules via
.markdownlint.json - Automatic link checking
- Heading hierarchy validation
Usage patterns
Manual linting workflow
Manual linting workflow
- Edit your file
- Press
<leader>llto run linters - Review diagnostics in the diagnostic list
- Fix issues
- Repeat
Unlike formatting (which runs on save), linting is manual to avoid excessive CPU usage during active editing.
Automatic linting (optional)
Automatic linting (optional)
To enable automatic linting on events, add an autocmd:
Integration with LSP
LSP vs linters
LSP vs linters
The configuration uses both LSP diagnostics and external linters:LSP handles:
- Real-time diagnostics during typing
- Language-specific errors and warnings
- Quick, incremental checks
- More comprehensive checks (e.g., golangci-lint runs 50+ linters)
- Project-wide analysis
- Style and best practice enforcement
- Checks that are too slow for real-time feedback
For JavaScript/TypeScript, Biome LSP handles real-time linting when
biome.json exists. eslint_d provides additional ESLint-specific checks.Common commands
<leader>ll- Run linters for current filetype:lua require('lint').try_lint()- Programmatically trigger linting- Use standard diagnostic navigation:
[d,]d,<leader>cd
Linter output is displayed as Neovim diagnostics, so all diagnostic commands and keymaps work with linter results.