134 lines
4.9 KiB
Lua
134 lines
4.9 KiB
Lua
require("mason").setup()
|
|
|
|
-- Add mason bin to PATH so vim.lsp.enable can find installed servers
|
|
vim.env.PATH = vim.fn.stdpath("data") .. "/mason/bin:" .. vim.env.PATH
|
|
|
|
require("mason-lspconfig").setup({
|
|
ensure_installed = {
|
|
"gopls",
|
|
"bashls",
|
|
"ansiblels",
|
|
"yamlls",
|
|
},
|
|
})
|
|
|
|
vim.lsp.config("gopls", {
|
|
cmd = { "gopls" },
|
|
filetypes = { "go", "gomod", "gowork", "gotmpl" },
|
|
root_markers = { "go.mod", "go.work", ".git" },
|
|
settings = {
|
|
gopls = {
|
|
analyses = {
|
|
unusedparams = true,
|
|
shadow = true,
|
|
nilness = true,
|
|
unusedwrite = true,
|
|
useany = true,
|
|
},
|
|
staticcheck = true,
|
|
gofumpt = true,
|
|
},
|
|
},
|
|
})
|
|
vim.lsp.config("bashls", {
|
|
cmd = { "bash-language-server", "start" },
|
|
filetypes = { "sh", "bash" },
|
|
})
|
|
vim.lsp.config("ansiblels", {
|
|
cmd = { "ansible-language-server", "--stdio" },
|
|
filetypes = { "yaml.ansible" },
|
|
root_markers = { "ansible.cfg", ".ansible-lint", "playbooks" },
|
|
})
|
|
vim.lsp.config("yamlls", {
|
|
cmd = { "yaml-language-server", "--stdio" },
|
|
filetypes = { "yaml", "yaml.docker-compose" },
|
|
})
|
|
|
|
vim.lsp.enable({ "gopls", "bashls", "ansiblels", "yamlls" })
|
|
|
|
-- Diagnostics UI
|
|
vim.diagnostic.config({
|
|
virtual_text = true,
|
|
signs = true,
|
|
underline = true,
|
|
update_in_insert = false,
|
|
float = { border = "rounded" },
|
|
})
|
|
|
|
-- LSP keymaps (set when an LSP attaches)
|
|
vim.api.nvim_create_autocmd("LspAttach", {
|
|
group = vim.api.nvim_create_augroup("lsp_keymaps", { clear = true }),
|
|
callback = function(ev)
|
|
local opts = { buffer = ev.buf }
|
|
|
|
-- Jump to definition, reusing an existing split if the file is already open
|
|
local function goto_definition_reuse()
|
|
local params = vim.lsp.util.make_position_params(0, "utf-8")
|
|
vim.lsp.buf_request(0, "textDocument/definition", params, function(err, result)
|
|
if err or not result or vim.tbl_isempty(result) then return end
|
|
local target = result[1] or result
|
|
local uri = target.uri or target.targetUri
|
|
local range = target.range or target.targetSelectionRange
|
|
local bufnr = vim.uri_to_bufnr(uri)
|
|
-- Check if file is already visible in a window
|
|
for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
|
|
if vim.api.nvim_win_get_buf(win) == bufnr then
|
|
vim.api.nvim_set_current_win(win)
|
|
local pos = range.start
|
|
vim.api.nvim_win_set_cursor(win, { pos.line + 1, pos.character })
|
|
return
|
|
end
|
|
end
|
|
-- Not open anywhere, use default behavior
|
|
vim.lsp.util.show_document(target, "utf-8", { focus = true })
|
|
end)
|
|
end
|
|
|
|
-- Navigation
|
|
vim.keymap.set("n", "gd", goto_definition_reuse, opts)
|
|
vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts)
|
|
vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts)
|
|
vim.keymap.set("n", "gr", vim.lsp.buf.references, opts)
|
|
vim.keymap.set("n", "gt", vim.lsp.buf.type_definition, opts)
|
|
|
|
-- Info
|
|
vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)
|
|
vim.keymap.set("n", "<C-k>", vim.lsp.buf.signature_help, opts)
|
|
vim.keymap.set("i", "<C-k>", vim.lsp.buf.signature_help, opts)
|
|
|
|
-- Actions
|
|
vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, opts)
|
|
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts)
|
|
vim.keymap.set("n", "<leader>f", function() vim.lsp.buf.format({ async = true }) end, opts)
|
|
|
|
-- Diagnostics
|
|
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)
|
|
vim.keymap.set("n", "gl", vim.diagnostic.open_float, opts)
|
|
end,
|
|
})
|
|
|
|
-- Auto-format and organize imports on save for Go
|
|
vim.api.nvim_create_autocmd("BufWritePre", {
|
|
group = vim.api.nvim_create_augroup("go_organize_imports", { clear = true }),
|
|
pattern = "*.go",
|
|
callback = function()
|
|
-- Organize imports via code action
|
|
local params = vim.lsp.util.make_range_params(0, "utf-8")
|
|
params.context = { only = { "source.organizeImports" } }
|
|
local result = vim.lsp.buf_request_sync(0, "textDocument/codeAction", params, 1000)
|
|
for _, res in pairs(result or {}) do
|
|
for _, action in pairs(res.result or {}) do
|
|
if action.edit then
|
|
vim.lsp.util.apply_workspace_edit(action.edit, "utf-8")
|
|
elseif action.command then
|
|
vim.lsp.buf.execute_command(action.command)
|
|
end
|
|
end
|
|
end
|
|
-- Format
|
|
vim.lsp.buf.format({ async = false })
|
|
end,
|
|
})
|