-- Mappings.
-- See `:help vim.diagnostic.*` for documentation on any of the below functions
local opts = { noremap=true, silent=true }
-- vim.keymap.set('n', '<leader>e', vim.diagnostic.open_float, opts)
-- vim.keymap.set('n', '<leader>h', vim.diagnostic.hide, opts)
vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, opts)
vim.keymap.set('n', ']d', vim.diagnostic.goto_next, opts)
vim.keymap.set('n', '<leader>q', vim.diagnostic.setloclist, opts)
-- Use an on_attach function to only map the following keys
-- after the language server attaches to the current buffer
vim.api.nvim_create_autocmd("LspAttach", {
callback = function(args)
local client = vim.lsp.get_client_by_id(args.data.client_id)
local bufopts = { noremap=true, silent=true, buffer=args.buf }
-- KEY MAP
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts)
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, bufopts)
vim.keymap.set('n', 'K', function() vim.lsp.buf.hover { border = { "", "" ,"", " ", "", "", "", " " } } end, bufopts)
vim.keymap.set('n', 'gI', vim.lsp.buf.implementation, bufopts)
vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, bufopts)
vim.keymap.set('n', '<leader>wa', vim.lsp.buf.add_workspace_folder, bufopts)
vim.keymap.set('n', '<leader>wr', vim.lsp.buf.remove_workspace_folder, bufopts)
vim.keymap.set('n', '<leader>wl', function()
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end, bufopts)
vim.keymap.set('n', '<leader>y', vim.lsp.buf.type_definition, bufopts)
vim.keymap.set('n', '<leader>V', vim.lsp.buf.rename, bufopts)
vim.keymap.set({'n','v'}, '<leader>ca', vim.lsp.buf.code_action, bufopts)
vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts)
vim.keymap.set('n', '<leader>=', function() vim.lsp.buf.format { async = true } end, bufopts)
-- DIAGNOSTICS
vim.api.nvim_create_autocmd("CursorMoved", {
callback = function()
vim.diagnostic.open_float(nil, {
focusable = false,
close_events = { "BufLeave", "CursorMoved", "InsertEnter", "FocusLost" },
source = false,
prefix = ' ',
scope = 'cursor',
})
end
})
-- -- PATCH: override all diagnostic highlights to be severity based
-- -- to mitigate severity being ignored in the special cases of DiagnosticDeprecated and DiagnosticUnnecessary
-- --
-- -- foollow relevant issues:
-- -- #26796 (nvim) https://github.com/neovim/neovim/issues/26796#issuecomment-3236801970
-- -- #1677 (kickstart.nvim)
-- -- #1550 (kickstart.nvim)
-- --
-- Create namespace for our custom highlights
local ns_id = vim.api.nvim_create_namespace('diagnostic_text_highlight')
-- Function to apply highlights to diagnostic ranges
local
-- Clear previous highlights
vim.api.nvim_buf_clear_namespace(0, ns_id, 0, -1)
-- Get diagnostics for current buffer
local diagnostics = vim.diagnostic.get(0)
for _, diagnostic in ipairs(diagnostics) do
local severity = diagnostic.severity
local start_line = diagnostic.lnum
local start_col = diagnostic.col
local end_line = diagnostic.end_lnum or start_line
local end_col = diagnostic.end_col or (start_col + 1)
-- Choose highlight group based on severity
local hl_group
if severity == vim.diagnostic.severity.ERROR then
hl_group = 'DiagnosticError'
elseif severity == vim.diagnostic.severity.WARN then
hl_group = 'DiagnosticWarn'
elseif severity == vim.diagnostic.severity.INFO then
hl_group = 'DiagnosticInfo'
elseif severity == vim.diagnostic.severity.HINT then
hl_group = 'DiagnosticHint'
end
-- Apply highlight to the specific range
if hl_group then
vim.highlight.range(
0, -- buffer (0 = current)
ns_id, -- namespace
hl_group, -- highlight group
{ start_line, start_col }, -- start position
{ end_line, end_col } -- end position
)
end
end
end
-- Create autocmd for DiagnosticChanged event
vim.api.nvim_create_autocmd('DiagnosticChanged', {
callback = highlight_diagnostic_text,
desc = 'Highlight diagnostic text with custom colors'
})
-- Also apply highlights when entering a buffer (for existing diagnostics)
vim.api.nvim_create_autocmd('BufEnter', {
callback = highlight_diagnostic_text,
desc = 'Apply diagnostic text highlights on buffer enter'
})
-- --
-- -- COMPLETION ( disabled while still immature, using nvim-blink for now )
-- -- Enable auto-completion. Note: Use CTRL-Y to select an item. |complete_CTRL-Y|
-- if client:supports_method('textDocument/completion') then
-- -- Optional: trigger autocompletion on EVERY keypress. May be slow!
-- local chars = {}; for i = 32, 126 do table.insert(chars, string.char(i)) end
-- client.server_capabilities.completionProvider.triggerCharacters = chars
-- vim.lsp.completion.enable(true, client.id, args.buf, {
-- autotrigger = true
-- })
-- end
-- -- FORMATTING
-- -- Auto-format ("lint") on save.
-- -- Usually not needed if server supports "textDocument/willSaveWaitUntil".
-- if not client:supports_method('textDocument/willSaveWaitUntil')
-- and client:supports_method('textDocument/formatting') then
-- vim.api.nvim_create_autocmd('BufWritePre', {
-- group = vim.api.nvim_create_augroup('my.lsp', {clear=false}),
-- buffer = args.buf,
-- callback = function()
-- vim.lsp.buf.format({ bufnr = args.buf, id = client.id, timeout_ms = 1000 })
-- end,
-- })
-- end
end,
})
-- CONFIGS
vim.diagnostic.config({
virtual_text = false,
-- signs = false,
signs = {
text = {
-- [vim.diagnostic.severity.ERROR] = "• ",
-- [vim.diagnostic.severity.WARN] = "• ",
-- [vim.diagnostic.severity.INFO] = "• ",
-- [vim.diagnostic.severity.HINT] = "• ",
[vim.diagnostic.severity.ERROR] = "",
[vim.diagnostic.severity.WARN] = "",
[vim.diagnostic.severity.INFO] = "",
[vim.diagnostic.severity.HINT] = "",
},
numhl = {
[vim.diagnostic.severity.ERROR] = "DiagnosticError",
[vim.diagnostic.severity.WARN] = "DiagnosticWarn",
[vim.diagnostic.severity.INFO] = "DiagnosticInfo",
[vim.diagnostic.severity.HINT] = "DiagnosticHint",
},
-- linehl = {
-- [vim.diagnostic.severity.ERROR] = "DiagnosticError",
-- [vim.diagnostic.severity.WARN] = "DiagnosticWarn",
-- [vim.diagnostic.severity.INFO] = "DiagnosticInfo",
-- [vim.diagnostic.severity.HINT] = "DiagnosticHint",
-- },
},
update_in_insert = false,
severity_sort = true,
float = {
border = { "", "" ,"", " ", "", "", "", " " },
},
})
--
vim.lsp.config('*', {
flags = {
debounce_text_changes = 150,
},
})
vim.lsp.config('hls', {
filetypes = { 'haskell', 'lhaskell', 'cabal' },
})
vim.lsp.config('lua_ls', {
root_markers = {},
settings = {
Lua = {
telemetry = {
enable = false,
},
runtime = { version = 'Lua 5.1' },
diagnostics = {
globals = { 'bit', 'vim', 'it', 'describe', 'before_each', 'after_each' },
},
},
},
on_init = function(client)
local nvim_settings = {
runtime = {
-- Tell the language server which version of Lua you're using
version = 'LuaJIT',
},
diagnostics = {
-- Get the language server to recognize the `vim` global
globals = {'vim'}
},
workspace = {
checkThirdParty = false,
library = {
-- Make the server aware of Neovim runtime files
vim.env.VIMRUNTIME,
vim.fn.stdpath('config'),
},
},
}
client.config.settings.Lua = vim.tbl_deep_extend(
'force',
client.config.settings.Lua,
nvim_settings
)
end,
})
vim.lsp.enable({
'lua_ls',
'rust_analyzer',
'hls',
'ts_ls'
})