diff --git a/roles/neovim/files/lua/opdavies/lsp/handlers.lua b/roles/neovim/files/lua/opdavies/lsp/handlers.lua
index dad5b59c..0b4d036c 100644
--- a/roles/neovim/files/lua/opdavies/lsp/handlers.lua
+++ b/roles/neovim/files/lua/opdavies/lsp/handlers.lua
@@ -18,30 +18,67 @@ M.setup = function()
   vim.diagnostic.config(config)
 end
 
-local capabilities = vim.lsp.protocol.make_client_capabilities()
+local function lsp_keymaps(bufnr)
+  local function map(...)
+    vim.api.nvim_buf_set_keymap(bufnr, ...)
+  end
+
+  local opts = { noremap = true, silent = true }
+
+  map("n", "<C-k>", "<cmd>lua vim.lsp.buf.signature_help()<CR>", opts)
+  map("n", "<space>D", "<cmd>lua vim.lsp.buf.type_definition()<CR>", opts)
+  map("n", "<space>ca", "<cmd>lua vim.lsp.buf.code_action()<CR>", opts)
+  map("n", "<space>e", "<cmd>lua vim.diagnostic.open_float()<CR>", opts)
+  map("n", "<space>rn", "<cmd>lua vim.lsp.buf.rename()<CR>", opts)
+  map("n", "K", "<cmd>lua vim.lsp.buf.hover()<CR>", opts)
+  map("n", "[d", "<cmd>lua vim.diagnostic.goto_prev()<CR>", opts)
+  map("n", "]d", "<cmd>lua vim.diagnostic.goto_next()<CR>", opts)
+  map("n", "gD", "<cmd>lua vim.lsp.buf.declaration()<CR>", opts)
+  map("n", "gd", "<cmd>lua vim.lsp.buf.definition()<CR>", opts)
+  map("n", "gi", "<cmd>lua vim.lsp.buf.implementation()<CR>", opts)
+  map("n", "gr", "<cmd>lua vim.lsp.buf.references()<CR>", opts)
+end
 
 local status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp")
 if not status_ok then
   return
 end
 
+custom_attach = function(client, bufnr)
+  print(client.name, bufnr)
 
-  -- keymap(bufnr, "n", "gD", "<cmd>lua vim.lsp.buf.declaration()<CR>", opts)
-  -- keymap(bufnr, "n", "gd", "<cmd>lua vim.lsp.buf.definition()<CR>", opts)
-  -- keymap(bufnr, "n", "K", "<cmd>lua vim.lsp.buf.hover()<CR>", opts)
-  -- keymap(bufnr, "n", "gi", "<cmd>lua vim.lsp.buf.implementation()<CR>", opts)
-  -- keymap(bufnr, "n", "<C-k>", "<cmd>lua vim.lsp.buf.signature_help()<CR>", opts)
-  -- keymap(bufnr, "n", "gr", "<cmd>lua vim.lsp.buf.references()<CR>", opts)
-local function lsp_keymaps(_, bufnr)
-  local opts = { noremap = true, silent = true }
-
-  local keymap = vim.api.nvim_buf_set_keymap
+  lsp_keymaps(bufnr)
 end
 
-M.on_attach = function(client, bufnr)
-  lsp_keymaps(client, bufnr)
+local custom_init = function(client)
+  client.config.flags = client.config.flags or {}
+  client.config.flags.allow_incremental_sync = true
 end
 
-M.capabilities = cmp_nvim_lsp.update_capabilities(capabilities)
+M.setup_server = function(server, config, lspconfig)
+  if not config then
+    return
+  end
+
+  if type(config) ~= "table" then
+    config = {}
+  end
+
+  config = vim.tbl_deep_extend("force", {
+    on_init = custom_init,
+    on_attach = custom_attach,
+    capabilities = updated_capabilities,
+    flags = {
+      debounce_text_changes = 50,
+    },
+  }, config)
+
+  lspconfig[server].setup(config)
+end
+
+local updated_capabilities = vim.lsp.protocol.make_client_capabilities()
+updated_capabilities = cmp_nvim_lsp.update_capabilities(updated_capabilities)
+
+M.capabilities = updated_capabilities
 
 return M
diff --git a/roles/neovim/files/lua/opdavies/lsp/init.lua b/roles/neovim/files/lua/opdavies/lsp/init.lua
index f00e5461..d00082c2 100644
--- a/roles/neovim/files/lua/opdavies/lsp/init.lua
+++ b/roles/neovim/files/lua/opdavies/lsp/init.lua
@@ -3,38 +3,28 @@ if not status_ok then
   return
 end
 
-local opts = {
-  on_attach = require("opdavies.lsp.handlers").on_attach,
-  capabilities = require("opdavies.lsp.handlers").capabilities,
-}
-
-local servers = {
-  "ansiblels",
-  "bashls",
-  "cssls",
-  "html",
-  "tsserver",
-  "vuels",
-  "yamlls",
-}
-
-for _, lsp in ipairs(servers) do
-  lspconfig[lsp].setup(opts)
-end
-
-local intelephense_opts = require "opdavies.lsp.settings.intelephense"
-lspconfig.intelephense.setup {
-  vim.tbl_deep_extend("force", intelephense_opts, opts),
-}
-
-local sumneko_lua_opts = require "opdavies.lsp.settings.sumneko_lua"
-lspconfig.sumneko_lua.setup(vim.tbl_deep_extend("force", sumneko_lua_opts, opts))
-
-local tailwindcss_opts = require "opdavies.lsp.settings.tailwindcss"
-lspconfig.tailwindcss.setup {
-  vim.tbl_deep_extend("force", tailwindcss_opts, opts),
-}
-
 require("opdavies.lsp.handlers").setup()
 
+local servers = {
+  ansiblels = true,
+  bashls = true,
+  cssls = true,
+  html = true,
+  tsserver = true,
+  vuels = true,
+  yamlls = true,
+
+  intelephense = {
+    filetypes = { "php", "module", "test", "inc" },
+  },
+
+  tailwindcss = {
+    filetypes = { "html", "html.twig" },
+  },
+}
+
+for server, config in pairs(servers) do
+  require("opdavies.lsp.handlers").setup_server(server, config, lspconfig)
+end
+
 require "opdavies.lsp.null-ls"
diff --git a/roles/neovim/files/lua/opdavies/lsp/settings/intelephense.lua b/roles/neovim/files/lua/opdavies/lsp/settings/intelephense.lua
deleted file mode 100644
index 51bc0417..00000000
--- a/roles/neovim/files/lua/opdavies/lsp/settings/intelephense.lua
+++ /dev/null
@@ -1,3 +0,0 @@
-return {
-  filetypes = { "php", "module", "test", "inc" },
-}
diff --git a/roles/neovim/files/lua/opdavies/lsp/settings/sumneko_lua.lua b/roles/neovim/files/lua/opdavies/lsp/settings/sumneko_lua.lua
deleted file mode 100644
index 2512baf9..00000000
--- a/roles/neovim/files/lua/opdavies/lsp/settings/sumneko_lua.lua
+++ /dev/null
@@ -1,15 +0,0 @@
-return {
-  settings = {
-    Lua = {
-      diagnostics = {
-        globals = { "use", "vim" },
-      },
-      workspace = {
-        library = {
-          [vim.fn.expand "$VIMRUNTIME/lua"] = true,
-          [vim.fn.stdpath "config" .. "/lua"] = true,
-        },
-      },
-    },
-  },
-}
diff --git a/roles/neovim/files/lua/opdavies/lsp/settings/tailwindcss.lua b/roles/neovim/files/lua/opdavies/lsp/settings/tailwindcss.lua
deleted file mode 100644
index 3a994b3b..00000000
--- a/roles/neovim/files/lua/opdavies/lsp/settings/tailwindcss.lua
+++ /dev/null
@@ -1,3 +0,0 @@
-return {
-  filetypes = { "html", "html.twig", "lua" },
-}