vim.api.nvim_create_autocmd('LspAttach', {
	group = vim.api.nvim_create_augroup('UserLspAttach', { clear = true }),
	callback = function(args)
		local client = assert(vim.lsp.get_client_by_id(args.data.client_id))

		local opts = { noremap = true, silent = true }
		local k = vim.keymap

		k.set('n', 'gd', function() vim.lsp.buf.definition() end, { desc = '[g]oto [d]efinition' })
		k.set('n', '<leader>lt', ':checkhealth vim.lsp<cr>', opts)
		k.set('n', '<leader>lr', vim.lsp.buf.rename, opts)
		k.set('n', '<leader>la', vim.lsp.buf.code_action, opts)
		k.set('n', 'gr', vim.lsp.buf.references, opts)
		k.set('n', '[d', function() vim.diagnostic.jump({ count = -1, float = true }) end, opts)
		k.set('n', ']d', function() vim.diagnostic.jump({ count = 1, float = true }) end, opts)

		-- Auto-formatting (with Editorconfig)
		if client:supports_method 'textDocument/willSaveWaitUntil' and client:supports_method 'textDocument/formatting' then
			vim.api.nvim_create_autocmd('BufWritePre', {
				group = vim.api.nvim_create_augroup('UserLspAttach', { clear = false }),
				buffer = args.buf,
				callback = function()
					vim.lsp.buf.format { bufnr = args.buf, id = client.id, timeout_ms = 1000 }
				end,
			})
		end
	end,
})
vim.o.completeopt = 'menuone,noinsert,popup,fuzzy,noselect'
vim.o.winborder = 'rounded' -- rounded borders in floating windows

-- Diagnostics
vim.diagnostic.config {
	severity_sort = true,
	signs = true,
	underline = true,
	virtual_text = true,
	-- virtual_lines = true,
}

-- Configs
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities.textDocument.completion.completionItem.snippetSupport = true

vim.lsp.config('*', {
	capabilities = capabilities,
})

vim.lsp.enable({
	"astro",
	"basedpyright",
	"clangd",
	"emmet_ls",
	"luals",
	"nixd",
	"tailwindcss",
	"ts_ls",
})
