Skip to content

feat(diagnostics): enhance diagnostics display, dynamic virtual text like VS Code Error Lens #1628

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 46 additions & 22 deletions init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -628,33 +628,57 @@ require('lazy').setup({

-- Diagnostic Config
-- See :help vim.diagnostic.Opts
local diagnostic_icons = {
[vim.diagnostic.severity.ERROR] = 'σ°…š ',
[vim.diagnostic.severity.WARN] = 'σ°€ͺ ',
[vim.diagnostic.severity.INFO] = 'σ°‹½ ',
[vim.diagnostic.severity.HINT] = '󰌢 ',
}

vim.diagnostic.config {
update_in_insert = true,
severity_sort = true,
float = { border = 'rounded', source = 'if_many' },
underline = { severity = vim.diagnostic.severity.ERROR },
signs = vim.g.have_nerd_font and {
text = {
[vim.diagnostic.severity.ERROR] = 'σ°…š ',
[vim.diagnostic.severity.WARN] = 'σ°€ͺ ',
[vim.diagnostic.severity.INFO] = 'σ°‹½ ',
[vim.diagnostic.severity.HINT] = '󰌢 ',
},
} or {},
virtual_text = {
source = 'if_many',
spacing = 2,
format = function(diagnostic)
local diagnostic_message = {
[vim.diagnostic.severity.ERROR] = diagnostic.message,
[vim.diagnostic.severity.WARN] = diagnostic.message,
[vim.diagnostic.severity.INFO] = diagnostic.message,
[vim.diagnostic.severity.HINT] = diagnostic.message,
}
return diagnostic_message[diagnostic.severity]
end,
},
underline = true, -- { severity = vim.diagnostic.severity.ERROR }
signs = vim.g.have_nerd_font and { text = diagnostic_icons } or {},
}

-- Diagnostic configuration similar to VS Code's Error Lens.
-- In insert mode, diagnostics are displayed as inline virtual text.
-- In normal mode, diagnostics are shown as virtual lines below the affected lines.
---@param enable boolean
local function set_virtual_text(enable)
vim.diagnostic.config {
virtual_lines = not enable and {
format = function(diagnostic)
return (diagnostic_icons[diagnostic.severity] or '') .. diagnostic.message
end,
} or false,
virtual_text = enable and {
source = 'if_many',
spacing = 2,
format = function(diagnostic)
return (diagnostic_icons[diagnostic.severity] or '') .. diagnostic.message
end,
} or false,
}
end

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should call set_virtual_text at least once outside of the autocmds.
Without doing that you will have no diagnostics at all, until you switch to insert mode for the first time.

Suggested change
set_virtual_text(false)

set_virtual_text(false)

vim.api.nvim_create_autocmd('InsertEnter', {
callback = function()
set_virtual_text(true)
end,
})

vim.api.nvim_create_autocmd('ModeChanged', {
pattern = 'i:*',
callback = function()
set_virtual_text(false)
end,
})

-- LSP servers and clients are able to communicate to each other what features they support.
-- By default, Neovim doesn't support everything that is in the LSP specification.
-- When you add blink.cmp, luasnip, etc. Neovim now has *more* capabilities.
Expand Down