return {
	{
		'neovim/nvim-lspconfig',
		event = { 'BufReadPre', 'BufNewFile' },
		dependencies = {
			{ 'williamboman/mason.nvim' },
			{ 'williamboman/mason-lspconfig.nvim' },
			{ 'hrsh7th/cmp-nvim-lsp' },
			{ 'mfussenegger/nvim-dap' },
			{ 'simrat39/rust-tools.nvim' },
			{
				'j-hui/fidget.nvim',
				opts = {
				},
			},
		},
		config = function()
			require('plugins.lsp.ui').setup()
			vim.diagnostic.config {
				underline = true,
				update_in_insert = true,
				signs = true,
				virtual_text = false,
				-- virtual_text = {
				-- 	source = 'if_many',
				-- 	prefix = '●',
				-- 	spacing = 5,
				-- 	-- this will set set the prefix to a function that returns the diagnostics icon based on the severity
				-- 	-- this only works on a recent 0.10.0 build. Will be set to "●" when not supported
				-- 	-- prefix = "icons",
				-- },
				float = {
					focusable = true,
					-- style = 'minimal',
					border = 'rounded',
					source = 'always',
					header = '',
					prefix = '',
				},
				severity_sort = true,
			}
		end,
	},
	{
		'williamboman/mason.nvim',
		cmd = 'Mason',
		opts = {
			settings = {
				ui = {
					border = 'rounded',
					icons = {
						package_installed = '◍',
						package_pending = '◍',
						package_uninstalled = '◍',
					},
				},
				-- log_level = vim.log.levels.INFO,
				max_concurrent_installers = 4,
			},
		},
	},
	{
		'jay-babu/mason-nvim-dap.nvim',
		dependencies = 'nvim-neotest/nvim-nio',
		opts = {
			ensure_installed = { --[[ 'javatest', 'javadbg', ]]
				'codelldb',
			},
			handlers = {
				function(config)
					-- all sources with no handler get passed here

					-- Keep original functionality
					require('mason-nvim-dap').default_setup(config)
				end,
				-- python = function(config)
				-- 	config.adapters = {
				-- 		type = "executable",
				-- 		command = "/usr/bin/python3",
				-- 		args = {
				-- 			"-m",
				-- 			"debugpy.adapter",
				-- 		},
				-- 	}
				-- 	require('mason-nvim-dap').default_setup(config) -- don't forget this!
				-- end,
			},
		},
	},
	{
		'williamboman/mason-lspconfig.nvim',
		dependencies = { 'jay-babu/mason-nvim-dap.nvim', 'rcarriga/nvim-dap-ui', 'Issafalcon/lsp-overloads.nvim' },
		config = function()
			require('mason').setup()
			local cmp_nvim_lsp = require 'cmp_nvim_lsp'
			local capabilities = cmp_nvim_lsp.default_capabilities()
			local lspconfig = require 'lspconfig'
			capabilities.textDocument.completion.completionItem = {
				documentationFormat = { 'markdown', 'plaintext' },
				snippetSupport = true,
				preselectSupport = true,
				insertReplaceSupport = true,
				labelDetailsSupport = true,
				deprecatedSupport = true,
				commitCharactersSupport = true,
				tagSupport = { valueSet = { 1 } },
				resolveSupport = {
					properties = {
						'documentation',
						'detail',
						'additionalTextEdits',
					},
				},
			}

			local function on_attach(client, bufnr)
				require('plugins.lsp.keymaps').on_attach(bufnr)
				require('plugins.lsp.ui').on_attach(client, bufnr)
				-- [[ vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') ]]
				if client.server_capabilities.signatureHelpProvider then
					require('lsp-overloads').setup(client, {
						ui = {
							max_width = 60,
							max_height = 8,
							floating_window_above_cur_line = true,
						},
						display_automatically = true, -- Uses trigger characters to automatically display the signature overloads when typing a method signature
					})
				end
				if client.name == 'jdtls' or client.name == 'jdt.ls' then
					-- client.server_capabilities.documentFormattingProvider = false
					vim.lsp.codelens.refresh()
					if JAVA_DAP_ACTIVE then
						require('jdtls').setup_dap { hotcodereplace = 'auto' }
						require('jdtls.setup').add_commands()
						require('jdtls.dap').setup_dap_main_class_configs()
					end
				end
				-- -- util.info(client.name .. " " .. (enable and "yes" or "no"), "format")
				client.server_capabilities.documentFormattingProvider = true
				client.server_capabilities.semanticTokensProvider = nil
			end

			require('mason-lspconfig').setup_handlers {
				function(server_name) -- default handler (optional)
					lspconfig[server_name].setup {
						on_attach = on_attach,
						capabilities = vim.deepcopy(capabilities),
					}
				end,
				['clangd'] = function()
					local clangd_flags = {
						'-j=5',
						'--all-scopes-completion',
						'--suggest-missing-includes',
						'--background-index',
						'--pch-storage=disk',
						'--cross-file-rename',
						'--log=info',
						'--completion-style=detailed',
						'--enable-config', -- clangd 11+ supports reading from .clangd configuration file
						'--clang-tidy',
						-- "--clang-tidy-checks=-*,llvm-*,clang-analyzer-*,modernize-*,-modernize-use-trailing-return-type",
						-- "--fallback-style=Google",
						-- "--header-insertion=never",
						-- "--query-driver=<list-of-white-listed-complers>"
					}
					lspconfig.clangd.setup {
						on_attach = on_attach,
						capabilities = capabilities,
						arg = {
							unpack(clangd_flags),
						},
					}
				end,
				['html'] = function()
					lspconfig.html.setup {
						on_attach = on_attach,
						capabilities = capabilities,
						filetypes = { 'html', 'jsp' },
					}
				end,
				['lua_ls'] = function()
					lspconfig.lua_ls.setup {
						on_attach = on_attach,
						capabilities = capabilities,
						flags = {
							debounce_text_changes = 150,
						},
						settings = {
							Lua = {
								diagnostics = {
									globals = { 'vim' },
								},
								-- workspace = {
								-- 	library = {
								-- 		[vim.fn.expand '$VIMRUNTIME/lua'] = true,
								-- 		[vim.fn.stdpath 'config' .. '/lua'] = true,
								-- 	},
								-- },
								telemetry = {
									enable = false,
								},
							},
						},
					}
				end,
				['jdtls'] = function() end,
				['rust_analyzer'] = function()
					local rt = require 'rust-tools'
					rt.setup {
						server = {
							on_attach = function(client, bufnr)
								require('plugins.lsp.keymaps').on_attach(bufnr)
								require('plugins.lsp.ui').on_attach(client, bufnr)
								client.server_capabilities.semanticTokensProvider = nil
								if client.server_capabilities.signatureHelpProvider then
									require('lsp-overloads').setup(client, {
										ui = {
											max_width = 60,
											max_height = 8,
											floating_window_above_cur_line = true,
										},
										display_automatically = true, -- Uses trigger characters to automatically display the signature overloads when typing a method signature
									})
								end
								-- Hover actions
								vim.keymap.set('n', '<C-space>',
									rt.hover_actions.hover_actions,
									{ buffer = bufnr })
								-- Code action groups
								vim.keymap.set(
									'n',
									'<Leader>a',
									rt.code_action_group.code_action_group,
									{ buffer = bufnr }
								)
							end,
							settings = {
								['rust-analyzer'] = {
									cargo = { features = 'all' },
									check = { allTargets = true },
								},
								procMacro = {
									enable = true,
								},
							},
						},
						-- debugging stuff
						dap = {
							adapter = {
								type = 'executable',
								command = 'lldb-vscode',
								name = 'rt_lldb',
							},
						},
					}
				end,
			}
		end,
	},
}
