You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

172 lines
6.6 KiB

local M = {}
M.install = { src = "https://github.com/neovim/nvim-lspconfig" }
M.setup = function()
vim.api.nvim_create_autocmd("LspAttach", {
group = vim.api.nvim_create_augroup("LspAttach", { clear = true }),
callback = function(event)
vim.keymap.set("n", "gr", function()
vim.lsp.buf.references()
end, { desc = "LSP References" })
vim.keymap.set("n", "gd", function()
vim.lsp.buf.definition()
end, { desc = "LSP Definition" })
-- LSP implementations
vim.keymap.set('n', 'gi', function()
vim.lsp.buf.implementation()
end, { desc = 'LSP implementation' })
-- LSP type definitions
vim.keymap.set('n', 'gt', function()
vim.lsp.buf.type_definition()
end, { desc = 'LSP type definition' })
-- LSP document symbols
vim.keymap.set('n', 'gs', function()
vim.lsp.buf.document_symbol()
end, { desc = 'LSP document symbols' })
-- LSP workspace symbols
vim.keymap.set('n', 'gS', function()
vim.lsp.buf.workspace_symbol()
end, { desc = 'LSP workspace symbols' })
-- LSP Declaration
vim.keymap.set("n", "gD", function()
vim.lsp.buf.declaration()
end, { desc = "Go to declaration" })
-- LSP Code Actions
vim.keymap.set({ "n", "v" }, "<leader>ca", function()
vim.lsp.buf.code_action()
end, { desc = "LSP Code Actions" })
-- LSP Rename
vim.keymap.set("n", "<leader>rn", function()
vim.lsp.buf.rename()
end, { desc = "LSP Rename" })
-- LSP diagnostics for current buffer
vim.keymap.set('n', '<leader>d', function()
vim.diagnostic.setloclist()
end, { desc = 'Buffer diagnostics' })
-- LSP Format
vim.keymap.set("n", "<leader>F", function()
vim.lsp.buf.format()
end, { desc = "LSP Format" })
-- LSP diagnostics for entire workspace
vim.keymap.set('n', '<leader>D', function()
vim.diagnostic.setqflist()
end, { desc = 'Workspace diagnostics' })
vim.keymap.set("n", "[d", function()
vim.diagnostic.jump({
count = -1,
on_jump = function()
vim.diagnostic.open_float()
end
})
end, { desc = "Go to previous diagnostic" })
vim.keymap.set("n", "]d", function()
vim.diagnostic.jump({
count = 1,
on_jump = function()
vim.diagnostic.open_float()
end
})
end, { desc = "Go to next diagnostic" })
vim.keymap.set("n", "[e", function()
vim.diagnostic.jump({
count = -1,
severity = vim.diagnostic.severity.ERROR,
on_jump = function()
vim.diagnostic.open_float()
end
})
end, { desc = "Go to previous diagnostic (error only)" })
vim.keymap.set("n", "]e", function()
vim.diagnostic.jump({
count = 1,
severity = vim.diagnostic.severity.ERROR,
on_jump = function()
vim.diagnostic.open_float()
end
})
end, { desc = "Go to next diagnostic (error only)" })
vim.keymap.set("n", "<leader>df", function()
vim.diagnostic.open_float()
end, { desc = "Show diagnostic in floating window" })
local client = vim.lsp.get_client_by_id(event.data.client_id)
if client and 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, event.buf, {
autotrigger = true,
-- Prevent auto-selection of first item
autocomplete = false
})
-- Map Ctrl+y to select first item and accept completion
vim.keymap.set('i', '<C-y>', function()
if vim.fn.pumvisible() == 1 then
-- If completion menu is visible, select first item if nothing selected, then accept
local selected = vim.fn.complete_info({'selected'}).selected
if selected == -1 then
-- Nothing selected, select first item then accept
return '<C-n><C-y>'
else
-- Something already selected, just accept
return '<C-y>'
end
else
return '<C-y>'
end
end, { expr = true, buffer = event.buf, desc = 'Accept completion' })
end
if client and client.server_capabilities.documentHighlightProvider then
vim.api.nvim_create_autocmd("LspDetach", {
group = vim.api.nvim_create_augroup("LspDetach", { clear = true }),
callback = function()
vim.lsp.buf.clear_references()
end,
})
end
end,
})
-- Load server configurations from separate files
local servers_path = vim.fn.stdpath("config") .. "/lua/lsp/servers"
local server_files = vim.fn.glob(servers_path .. "/*.lua", false, true)
local servers = {}
for _, file in ipairs(server_files) do
local server_name = vim.fn.fnamemodify(file, ":t:r")
local ok, server_config = pcall(require, "lsp.servers." .. server_name)
if ok then
servers[server_name] = server_config
else
vim.notify("Failed to load server config: " .. server_name, vim.log.levels.WARN)
end
end
-- Setup all servers using the new vim.lsp.config and vim.lsp.enable APIs
for server_name, server in pairs(servers) do
vim.lsp.config(server_name, server or {})
vim.lsp.enable(server_name)
end
end
return M