dotfiles/nvim/.config/nvim/lua/plugins/lsp.lua

229 lines
6.9 KiB
Lua

local function get_all_servers()
local servers = {}
for _, lang in pairs(Languages) do
if not lang.lsp then
goto continue
end
for name, conf in pairs(lang.lsp) do
servers[name] = vim.tbl_deep_extend("force", servers[name] or {}, conf)
end
::continue::
end
return servers
end
local lsp = {
{ -- pretty lsp 'peek' menus
"DNLHC/glance.nvim",
opts = { border = { enable = true }, theme = { enable = true, mode = "auto" } },
cmd = { "Glance" },
},
{
"neovim/nvim-lspconfig",
dependencies = {
{
"williamboman/mason-lspconfig.nvim",
opts = function()
local to_install = {}
local not_enabled = {}
for k, v in pairs(get_all_servers()) do
table.insert(to_install, k)
if v["disable"] and v["disable"] == true then
table.insert(not_enabled, k)
end
end
local tbl = {
ensure_installed = to_install,
automatic_enable = { exclude = not_enabled },
}
return tbl
end,
dependencies = { "williamboman/mason.nvim" },
cmd = { "LspInstall", "LspUninstall" },
},
{ "saghen/blink.cmp", optional = true },
},
event = "LazyFile",
opts = { servers = get_all_servers() },
init = function()
if require("core.util").is_available("which-key") then
require("which-key").add({ "<localleader>l", group = "language" })
end
end,
config = function(_, lspconfig_opts)
-- Display diagnostics as virtual text only if not in insert mode
-- /r/neovim/comments/12inp4c/disable_diagnostics_virtual_text_when_in_insert/jqqifwk/
vim.diagnostic.config({ virtual_text = true })
vim.api.nvim_create_autocmd("InsertEnter", {
callback = function()
vim.diagnostic.config({ virtual_text = false })
end,
})
vim.api.nvim_create_autocmd("InsertLeave", {
callback = function()
vim.diagnostic.config({ virtual_text = true })
end,
})
vim.fn.sign_define("DiagnosticSignError", { text = "", texthl = "DiagnosticSignError" })
vim.fn.sign_define("DiagnosticSignWarn", { text = "", texthl = "DiagnosticSignWarn" })
vim.fn.sign_define("DiagnosticSignInfo", { text = "", texthl = "DiagnosticSignInfo" })
vim.fn.sign_define("DiagnosticSignHint", { text = "", texthl = "DiagnosticSignHint" })
local function register(server_name, config, enabled)
if vim.fn.has("nvim-0.11") == 1 then
vim.lsp.config(server_name, config or {})
if enabled == false or vim.lsp.config[server_name]["autostart"] == false then
vim.lsp.enable(server_name, false)
else
vim.lsp.enable(server_name, true)
end
else
require("lspconfig")[server_name].setup(config)
end
end
if vim.fn.executable("nu") == 1 then
register("nushell")
end
-- arduino lsp only works if arduino-cli is installed
if vim.fn.executable("arduino-cli") == 1 then
register("arduino_language_server")
end
-- attach ltex for fitting ft only when spell checking becomes enabled
vim.api.nvim_create_autocmd("User", {
pattern = "SpellEnable",
callback = function()
local mapped = {}
local lang_map = {
en_us = "en-US",
en_gb = "en-GB",
de_de = "de-DE",
}
for _, v in ipairs(vim.opt.spelllang:get()) do
table.insert(mapped, lang_map[v])
end
vim.lsp.config("ltex", {
settings = { ltex = { language = mapped } },
})
-- single-shot setup: Enable for this buffer
-- but instantly disable again globally
vim.lsp.enable("ltex")
vim.lsp.enable("ltex", false)
end,
})
vim.api.nvim_create_autocmd("User", {
pattern = "SpellDisable",
callback = function()
vim.lsp.enable("ltex", false)
end,
})
end,
keys = { { "<leader>vs", ":LspInfo<cr>", desc = "LspInfo" } },
},
}
vim.api.nvim_create_autocmd("LspAttach", {
desc = "LSP actions",
callback = function(event)
local o = function(add_opts)
return vim.tbl_extend("force", { buffer = event.buf }, add_opts)
end
local map = vim.keymap.set
map("n", "K", "<cmd>lua vim.lsp.buf.hover()<cr>", o({ desc = "Hover definition" }))
map("n", "[e", "<cmd>lua vim.diagnostic.goto_prev()<cr>", o({ desc = "Previous diagnostic" }))
map("n", "]e", "<cmd>lua vim.diagnostic.goto_next()<cr>", o({ desc = "Next diagnostic" }))
map(
"n",
"[E",
"<cmd>lua vim.diagnostic.goto_prev({severity = vim.diagnostic.severity.ERROR})<cr>",
o({ desc = "Previous error" })
)
map(
"n",
"]E",
"<cmd>lua vim.diagnostic.goto_next({severity = vim.diagnostic.severity.ERROR})<cr>",
o({ desc = "Next error" })
)
map("n", "<localleader>ld", "<cmd>lua vim.diagnostic.open_float()<cr>", o({ desc = "Show line diagnostics" }))
map("n", "<localleader>la", "<cmd>lua vim.lsp.buf.code_action()<cr>", o({ desc = "Codeactions" }))
map("n", "<localleader>ln", "<cmd>lua vim.lsp.buf.rename()<cr>", o({ desc = "Rename element" }))
map("n", "<localleader>lc", "<cmd>lua vim.lsp.buf.declaration()<cr>", o({ desc = "Declaration" }))
map("n", "<localleader>ls", "<cmd>lua vim.lsp.buf.signature_help()<cr>", o({ desc = "Signature help" }))
map("n", "<localleader>lI", function()
vim.lsp.inlay_hint.enable(not vim.lsp.inlay_hint.is_enabled())
end, o({ desc = "Toggle inlay hints" }))
map("n", "<localleader>lE", function()
vim.diagnostic.enable(not vim.diagnostic.is_enabled())
end, o({ desc = "Toggle Diagnostics" }))
-- FIXME: Will be re-enabled with insert-mode autocmd above
map("n", "<localleader>lo", function()
local c = vim.diagnostic.config() or {}
vim.diagnostic.config({ virtual_text = not c["virtual_text"] })
end, o({ desc = "Toggle virtual diag text" }))
if vim.fn.has("nvim-0.11") == true then -- new feature https://gpanders.com/blog/whats-new-in-neovim-0-11/#virtual-lines
map("n", "<localleader>lO", function()
local c = vim.diagnostic.config() or {}
vim.diagnostic.config({ virtual_lines = not c["virtual_lines"] })
end, o({ desc = "Toggle virtual diag lines" }))
end
local pref = function(glances, telescope, fallback)
if glances and vim.fn.exists(":Glance") > 0 then
return glances
elseif telescope and vim.fn.exists(":Telescope") > 0 then
return telescope
else
return fallback
end
end
map(
"n",
"<localleader>lr",
pref(
"<cmd>Glance references<cr>",
"<cmd>Telescope lsp_references<cr>",
"<cmd>lua vim.lsp.buf.references()<cr>"
),
o({ desc = "References" })
)
map(
"n",
"<localleader>lf",
pref(
"<cmd>Glance definitions<cr>",
"<cmd>Telescope lsp_definitions<cr>",
"<cmd>lua vim.lsp.buf.definition()<cr>"
),
o({ desc = "Definition" })
)
map(
"n",
"<localleader>lt",
pref(
"<cmd>Glance type_definitions<cr>",
"<cmd>Telescope lsp_type_definitions<cr>",
"<cmd>lua vim.lsp.buf.type_definition()<cr>"
),
o({ desc = "Type definition" })
)
map(
"n",
"<localleader>lm",
pref(
"<cmd>Glance implementations<cr>",
"<cmd>Telescope lsp_implementations<cr>",
"<cmd>lua vim.lsp.buf.implementation()<cr>"
),
o({ desc = "Implementation" })
)
end,
})
return lsp