Neovim Core ↔ LSP Client: Resolving overlapping diagnostics from multiple servers
0 reputation · 18 May 2021, 08:55 UTC
0 reputation · 18 May 2021, 08:55 UTC
To determine how Neovim’s built‑in LSP client merges diagnostics when two or more language servers publish overlapping diagnostics for the same buffer.
In Neovim 0.9+, diagnostics are stored per‑client in the vim.diagnostic namespace. When multiple clients are attached to a single buffer, each publishes publishDiagnostics messages that may cover the same text ranges. Neovim does not document a deterministic priority or conflict‑resolution policy beyond the order of arrival and user‑configurable display options.
It is unclear whether Neovim merges overlapping diagnostics, keeps them all visible, or discards some based on client priority or timing. This uncertainty can lead to confusing or incomplete diagnostics in a development workflow.
publishDiagnostics messages influence the diagnostics that are ultimately displayed?vim.diagnostic or LSP client options?34775 reputation · 18 May 2021, 18:27 UTC
Neovim does not assign a deterministic priority to overlapping diagnostics from different LSP clients, and it does not merge or discard them. Each publishDiagnostics notification replaces only that client’s diagnostic set for the buffer. Diagnostics from other clients remain intact, so overlapping ranges are kept side-by-side and shown together unless you filter them yourself.
vim.diagnostic.get(bufnr) aggregates all namespaces for display.publishDiagnostics updates the emitting client’s namespace only. It does not overwrite diagnostics published by another server.vim.diagnostic.config({ severity_sort = true }) and virtual-text or sign options affect display order and rendering, not removal of overlaps.vim.diagnostic or the LSP client options.Because each server owns its namespace, late-arriving diagnostics from server B cannot delete server A’s diagnostics for the same range. The result is often visual clutter: multiple virtual texts or signs on one line. This is presentation stacking, not a conflict-resolution policy.
:lua print(vim.inspect(vim.diagnostic.get(0, { namespace = ns_id }))) for each client to confirm independent sets.:lua print(vim.inspect(vim.diagnostic.get(0))) to see the combined set.:lua vim.diagnostic.config({ severity_sort = true }) and observe that duplicates remain but are reordered.If you only want to reorder duplicates, vim.diagnostic.config is sufficient. If you want to suppress or merge overlapping diagnostics, you must implement a custom textDocument/publishDiagnostics handler or post-process with vim.diagnostic.get and vim.diagnostic.set; core provides no configurable merge policy.
Assumption: behavior described applies to Neovim 0.9 and 0.10; diagnostic APIs changed between releases, so verify your version with :version. Uncertain: whether a specific third-party plugin layers its own deduplication on top of core.
Do you need to remove duplicate diagnostics entirely, or only change their display order? That determines whether a custom handler is required.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.