-
Notifications
You must be signed in to change notification settings - Fork 2.1k
UI Customization
Note: these instruction assume Neovim 0.6.0 or later!
Floating windows with borders are built-into the neovim core handler. The borders can be styled by passing in a character and highlight group. Highlight groups must be set with an autocmd to avoid being overwritten by your colorscheme.
vim.cmd [[autocmd! ColorScheme * highlight NormalFloat guibg=#1f2335]]
vim.cmd [[autocmd! ColorScheme * highlight FloatBorder guifg=white guibg=#1f2335]]
local border = {
{"🭽", "FloatBorder"},
{"▔", "FloatBorder"},
{"🭾", "FloatBorder"},
{"▕", "FloatBorder"},
{"🭿", "FloatBorder"},
{"▁", "FloatBorder"},
{"🭼", "FloatBorder"},
{"▏", "FloatBorder"},
}
-- LSP settings (for overriding per client)
local handlers = {
["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, {border = border}),
["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, {border = border }),
}
-- Do not forget to use the on_attach function
require 'lspconfig'.myserver.setup { handlers=handlers }
-- To instead override globally
local orig_util_open_floating_preview = vim.lsp.util.open_floating_preview
function vim.lsp.util.open_floating_preview(contents, syntax, opts, ...)
opts = opts or {}
opts.border = opts.border or border
return orig_util_open_floating_preview(contents, syntax, opts, ...)
end
require 'lspconfig'.myservertwo.setup {}
local M = {}
M.icons = {
Class = " ",
Color = " ",
Constant = " ",
Constructor = " ",
Enum = "了 ",
EnumMember = " ",
Field = " ",
File = " ",
Folder = " ",
Function = " ",
Interface = "ﰮ ",
Keyword = " ",
Method = "ƒ ",
Module = " ",
Property = " ",
Snippet = " ",
Struct = " ",
Text = " ",
Unit = " ",
Value = " ",
Variable = " ",
}
function M.setup()
local kinds = vim.lsp.protocol.CompletionItemKind
for i, kind in ipairs(kinds) do
kinds[i] = M.icons[kind] or kind
end
end
return M
You can configure diagnostic options globally. See :help vim.diagnostic.config
for more advanced customization options.
vim.diagnostic.config({
virtual_text = true,
signs = true,
underline = true,
update_in_insert = false,
severity_sort = false,
})
Note: With the default settings, you will not see updated diagnostics until you leave insert mode. Set update_in_insert = true
if you want diagnostics to update while in insert mode.
local signs = { Error = " ", Warn = " ", Hint = " ", Info = " " }
for type, icon in pairs(signs) do
local hl = "DiagnosticSign" .. type
vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = hl })
end
function PrintDiagnostics(opts, bufnr, line_nr, client_id)
bufnr = bufnr or 0
line_nr = line_nr or (vim.api.nvim_win_get_cursor(0)[1] - 1)
opts = opts or {['lnum'] = line_nr}
local line_diagnostics = vim.diagnostic.get(bufnr, opts)
if vim.tbl_isempty(line_diagnostics) then return end
local diagnostic_message = ""
for i, diagnostic in ipairs(line_diagnostics) do
diagnostic_message = diagnostic_message .. string.format("%d: %s", i, diagnostic.message or "")
print(diagnostic_message)
if i ~= #line_diagnostics then
diagnostic_message = diagnostic_message .. "\n"
end
end
vim.api.nvim_echo({{diagnostic_message, "Normal"}}, false, {})
end
vim.cmd [[ autocmd! CursorHold * lua PrintDiagnostics() ]]
-- You will likely want to reduce updatetime which affects CursorHold
-- note: this setting is global and should be set only once
vim.o.updatetime = 250
vim.cmd [[autocmd! CursorHold,CursorHoldI * lua vim.diagnostic.open_float(nil, {focus=false})]]
For diagnostics for specific cursor position
vim.cmd [[autocmd! CursorHold,CursorHoldI * lua vim.diagnostic.open_float(nil, {focus=false, scope="cursor"})]]
After neovim 0.7, put the code below into on_attach()
vim.api.nvim_create_autocmd("CursorHold", {
buffer = bufnr,
callback = function()
local opts = {
focusable = false,
close_events = { "BufLeave", "CursorMoved", "InsertEnter", "FocusLost" },
border = 'rounded',
source = 'always',
prefix = ' ',
scope = 'cursor',
}
vim.diagnostic.open_float(nil, opts)
end
})
See https://www.reddit.com/r/neovim/comments/mvhfw7/can_built_in_lsp_diagnostics_be_limited_to_show_a/
local function goto_definition(split_cmd)
local util = vim.lsp.util
local log = require("vim.lsp.log")
local api = vim.api
-- note, this handler style is for neovim 0.5.1/0.6, if on 0.5, call with function(_, method, result)
local handler = function(_, result, ctx)
if result == nil or vim.tbl_isempty(result) then
local _ = log.info() and log.info(ctx.method, "No location found")
return nil
end
if split_cmd then
vim.cmd(split_cmd)
end
if vim.tbl_islist(result) then
util.jump_to_location(result[1])
if #result > 1 then
util.set_qflist(util.locations_to_items(result))
api.nvim_command("copen")
api.nvim_command("wincmd p")
end
else
util.jump_to_location(result)
end
end
return handler
end
vim.lsp.handlers["textDocument/definition"] = goto_definition('split')
vim.diagnostic.config({
virtual_text = {
source = "always", -- Or "if_many"
},
float = {
source = "always", -- Or "if_many"
},
})
By default, this character is a square icon (■).
vim.diagnostic.config({
virtual_text = {
prefix = '■', -- Could be '●', '▎', 'x'
}
})
See the properties of the signs with sign list
.
vim.cmd [[
highlight! DiagnosticLineNrError guibg=#51202A guifg=#FF0000 gui=bold
highlight! DiagnosticLineNrWarn guibg=#51412A guifg=#FFA500 gui=bold
highlight! DiagnosticLineNrInfo guibg=#1E535D guifg=#00FFFF gui=bold
highlight! DiagnosticLineNrHint guibg=#1E205D guifg=#0000FF gui=bold
sign define DiagnosticSignError text= texthl=DiagnosticSignError linehl= numhl=DiagnosticLineNrError
sign define DiagnosticSignWarn text= texthl=DiagnosticSignWarn linehl= numhl=DiagnosticLineNrWarn
sign define DiagnosticSignInfo text= texthl=DiagnosticSignInfo linehl= numhl=DiagnosticLineNrInfo
sign define DiagnosticSignHint text= texthl=DiagnosticSignHint linehl= numhl=DiagnosticLineNrHint
]]
Add the following to your on_attach (this allows checking server capabilities to avoid calling invalid commands.
if client.resolved_capabilities.document_highlight then
vim.cmd [[
hi! LspReferenceRead cterm=bold ctermbg=red guibg=LightYellow
hi! LspReferenceText cterm=bold ctermbg=red guibg=LightYellow
hi! LspReferenceWrite cterm=bold ctermbg=red guibg=LightYellow
]]
vim.api.nvim_create_augroup('lsp_document_highlight', {
clear = false
})
vim.api.nvim_clear_autocmds({
buffer = bufnr,
group = 'lsp_document_highlight',
})
vim.api.nvim_create_autocmd({ 'CursorHold', 'CursorHoldI' }, {
group = 'lsp_document_highlight',
buffer = bufnr,
callback = vim.lsp.buf.document_highlight,
})
vim.api.nvim_create_autocmd('CursorMoved', {
group = 'lsp_document_highlight',
buffer = bufnr,
callback = vim.lsp.buf.clear_references,
})
end
Note this requires Neovim v0.7 which introduces vim.keymap.set
. If you are using Neovim with version prior to v0.7 then use the following:
Click to expand
if client.resolved_capabilities.document_highlight then
vim.cmd [[
hi! LspReferenceRead cterm=bold ctermbg=red guibg=LightYellow
hi! LspReferenceText cterm=bold ctermbg=red guibg=LightYellow
hi! LspReferenceWrite cterm=bold ctermbg=red guibg=LightYellow
augroup lsp_document_highlight
autocmd! * <buffer>
autocmd! CursorHold <buffer> lua vim.lsp.buf.document_highlight()
autocmd! CursorHoldI <buffer> lua vim.lsp.buf.document_highlight()
autocmd! CursorMoved <buffer> lua vim.lsp.buf.clear_references()
augroup END
]]
end