Workspace-wide diagnostics for Neovim LSP. Opens all workspace files in the background to trigger LSP diagnostics across your entire project.
- Async file reading with
vim.uv(non-blocking) - Chunked processing to keep UI responsive
- File list caching with configurable TTL
- Early filtering by extension and ignore patterns
- Waits for LSP server to initialize before triggering
- Progress notifications (supports fidget.nvim, noice.nvim via LSP progress protocol)
- Neovim >= 0.10.0
- Git (for
git ls-files)
{
'smnatale/workspace-diagnostics.nvim',
event = 'LspAttach',
opts = {},
}use {
'smnatale/workspace-diagnostics.nvim',
config = function()
require('workspace-diagnostics').setup()
end
}require('workspace-diagnostics').setup({
-- Trigger workspace diagnostics automatically on LspAttach
auto_trigger = true,
-- File list cache TTL in seconds
cache_ttl = 300,
-- Number of files to process per async tick
chunk_size = 10,
-- Delay in ms between processing chunks
chunk_delay = 1,
-- Show start/complete notifications via vim.notify()
notify_progress = true,
-- Use LSP progress protocol (works with fidget.nvim, noice.nvim, etc.)
lsp_progress = true,
-- Only run workspace diagnostics for these LSP servers
allowed_lsps = {
'ts_ls',
'eslint',
},
-- File extensions to include
allowed_extensions = {
'.ts',
'.tsx',
'.js',
'.jsx',
'.mjs',
'.cjs',
},
-- Directory patterns to ignore
ignore_dirs = {
'/.yarn/',
'/node_modules/',
'/dist/',
'/build/',
},
})| Command | Description |
|---|---|
:WorkspaceDiagnostics |
Trigger workspace diagnostics for attached LSP clients |
:WorkspaceDiagnosticsRefresh |
Force refresh (clears cache and re-triggers) |
:WorkspaceDiagnosticsStatus |
Show current status (cached files, processing state) |
local wd = require('workspace-diagnostics')
-- Manually trigger for a specific client
wd.trigger(client, bufnr, force_refresh)
-- Get current status
local status = wd.status()
-- Returns: { cached_files, cache_age, processing, triggered_clients }
-- Clear the file cache
wd.clear_cache()- On
LspAttach, the plugin waits for the LSP server to fully initialize - Collects workspace files using
git ls-files - Filters files by extension and ignore patterns
- Reads files asynchronously using
vim.uv(libuv) - Sends
textDocument/didOpennotifications to the LSP server - Processes files in chunks to keep the UI responsive
For faster processing (may cause micro-stutters):
{
chunk_size = 50, -- Process more files per tick
chunk_delay = 0, -- No delay between chunks
}For smoother UI (slower total time):
{
chunk_size = 5, -- Fewer files per tick
chunk_delay = 10, -- Longer delay between chunks
}This plugin supports the LSP $/progress protocol, which means it works automatically with:
- fidget.nvim
- noice.nvim
- Any other plugin that subscribes to LSP progress
Progress is reported per-chunk to avoid UI spam. The two notification options are mutually exclusive - lsp_progress takes precedence when enabled:
{
lsp_progress = true, -- (default) LSP $/progress protocol for fidget, noice, etc.
notify_progress = true, -- vim.notify() fallback (only used if lsp_progress = false)
}If you don't use fidget.nvim or similar, set lsp_progress = false to use vim.notify() instead.
- artemave/workspace-diagnostics.nvim - Similar plugin that inspired this one
- vim.lsp.buf.workspace_diagnostics() - Native Neovim support (merged June 2025, available in nightly). Uses the LSP
workspace/diagnosticmethod which requires server support - TypeScript language servers don't support this yet (tsgo tracking issue). This plugin usestextDocument/didOpeninstead, which works with any LSP server.
MIT