development/templates/nvim/lua/lsp.lua.j2

222 lines
5.9 KiB
Django/Jinja

-- {{ ansible_managed }}
--use an on_attach function to only map the following keys
--after the language server attaches to the current buffer
local on_attach = function(client, bufnr)
local opts = { buffer = bufnr, noremap = true, silent = true }
vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, opts)
vim.keymap.set('n', 'gd', vim.lsp.buf.definition, opts)
vim.keymap.set('n', 'K', vim.lsp.buf.hover, opts)
vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, opts)
vim.keymap.set('n', '<C-k>', vim.lsp.buf.signature_help, opts)
vim.keymap.set('n', '<space>wa', vim.lsp.buf.add_workspace_folder, opts)
vim.keymap.set('n', '<space>wr', vim.lsp.buf.remove_workspace_folder, opts)
vim.keymap.set('n', '<space>wl', function()
print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
end, opts)
vim.keymap.set('n', '<space>D', vim.lsp.buf.type_definition, opts)
vim.keymap.set('n', '<space>rn', vim.lsp.buf.rename, opts)
vim.keymap.set('n', 'gr', vim.lsp.buf.references, opts)
vim.keymap.set('n', '<space>e', vim.diagnostic.open_float, 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', '<space>q', vim.diagnostic.setloclist, opts)
vim.keymap.set('n', '<space>la', vim.lsp.buf.code_action, opts)
end
--enable some language servers with the additional completion capabilities
--offered by nvim-cmp
local servers = {
{% for item in language_servers %}
{% if item.auto_setup and not loop.last %}
'{{ item.server_name }}',
{% elif item.auto_setup %}
'{{ item.server_name }}'
{% endif %}
{% endfor %}
}
--add additional capabilities supported by nvim-cmp
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities = require('cmp_nvim_lsp').default_capabilities(capabilities)
local nvim_lsp = require('lspconfig')
for _, lsp in ipairs(servers) do
nvim_lsp[lsp].setup {
on_attach = on_attach,
capabilities = capabilities,
}
end
local util = require('lspconfig/util')
{% if ansible_facts.os_family == 'Archlinux' %}
local python_root_dir = function(fname)
return util.root_pattern('.git', 'setup.cfg', 'requirements')(fname) or
util.path.dirname(fname)
end
nvim_lsp.ruff.setup {
on_attach = on_attach,
capabilities = capabilities,
root_dir = python_root_dir
}
nvim_lsp.pyright.setup {
settings = {
pyright = {
-- Using Ruff's import organizer
disableOrganizeImports = true,
},
},
}
local snippet_capabilities = vim.deepcopy(capabilities);
snippet_capabilities.textDocument.completion.completionItem.snippetSupport = true
nvim_lsp.html.setup {
on_attach = on_attach,
capabilities = snippet_capabilities,
filetypes = { 'html', 'htmldjango' },
}
nvim_lsp.cssls.setup {
on_attach = on_attach,
capabilities = snippet_capabilities,
}
nvim_lsp.jsonls.setup {
on_attach = on_attach,
capabilities = snippet_capabilities,
}
{% endif %}
nvim_lsp.yamlls.setup {
on_attach = on_attach,
capabilities = capabilities,
filetypes = { 'yaml', 'yaml.ansible', 'yaml.docker-compose', 'yaml.gitlab' }
}
local cmp = require('cmp')
local luasnip = require('luasnip')
cmp.setup {
sources = {
{ name = 'nvim_lsp', },
{ name = 'buffer' },
{ name = 'path' },
{ name = 'nvim_lua' },
{
name = 'omni',
option = {
disable_omnifuncs = { 'v:lua.vim.lsp.omnifunc' }
}
},
{ name = 'luasnip', }, -- TODO: add snippets
},
formatting = {
format = function(entry, vim_item)
if entry.source.name == 'nvim_lsp' then
vim_item.menu = string.format('[%s]', entry.source.source.client.name)
else
vim_item.menu = string.format('[%s]', entry.source.name)
end
return vim_item
end,
},
mapping = cmp.mapping.preset.insert({
['<C-d>'] = cmp.mapping.scroll_docs(-4),
['<C-f>'] = cmp.mapping.scroll_docs(4),
['<C-Space>'] = cmp.mapping.complete(),
['<C-e>'] = cmp.mapping.close(),
['<CR>'] = cmp.mapping.confirm {
behavior = cmp.ConfirmBehavior.Replace,
select = true,
},
['<Tab>'] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif luasnip.expand_or_jumpable() then
luasnip.expand_or_jump()
else
fallback()
end
end, { 'i', 's' }),
['S-<Tab>'] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_prev_item()
elseif luasnip.jumpable(-1) then
luasnip.jump(-1)
else
fallback()
end
end, { 'i', 's' }),
}),
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
}
vim.diagnostic.config {
float = {
suffix = function(diagnostic)
return (' %s | [%s]'):format(diagnostic.code, diagnostic.source)
end
},
}
local enable_formatting = os.getenv("ENABLE_FORMATTING")
-- format buffers before saving for specific LSPs
if (enable_formatting) then
local excluded_clients = { 'pyright' }
vim.api.nvim_create_autocmd('LspAttach', {
group = vim.api.nvim_create_augroup('lsp', { clear = true }),
callback = function(args)
vim.api.nvim_create_autocmd('BufWritePre', {
buffer = args.buf,
callback = function()
local formatting_clients = vim.lsp.get_clients {
bufnr = args.buf,
method = 'textDocument/formatting'
}
local filtered_clients = {}
for _, client in pairs(formatting_clients) do
if vim.list_contains(excluded_clients, client.name) then
goto skip
end
table.insert(filtered_clients, client.name)
::skip::
end
if #filtered_clients == 0 then
return
end
vim.lsp.buf.format {
filter = function(client)
return vim.list_contains(filtered_clients, client.name)
end,
async = false,
id = args.data.client_id
}
end,
})
end
})
end