diff --git a/roles/neovim/files/lua/opdavies/keymap.lua b/roles/neovim/files/lua/opdavies/keymap.lua
new file mode 100644
index 00000000..92724d7f
--- /dev/null
+++ b/roles/neovim/files/lua/opdavies/keymap.lua
@@ -0,0 +1,11 @@
+local M = {}
+
+M.imap = function(tbl)
+  vim.keymap.set("i", tbl[1], tbl[2], tbl[3])
+end
+
+M.nmap = function(tbl)
+  vim.keymap.set("n", tbl[1], tbl[2], tbl[3])
+end
+
+return M
diff --git a/roles/neovim/files/lua/opdavies/lsp/handlers.lua b/roles/neovim/files/lua/opdavies/lsp/handlers.lua
deleted file mode 100644
index ec082ae2..00000000
--- a/roles/neovim/files/lua/opdavies/lsp/handlers.lua
+++ /dev/null
@@ -1,82 +0,0 @@
-local M = {}
-
-M.setup = function()
-  local config = {
-    virtual_text = true,
-    update_in_insert = true,
-    underline = true,
-    severity_sort = true,
-    float = {
-      focusable = false,
-      style = "minimal",
-      source = "always",
-      header = "",
-      prefix = "",
-    },
-  }
-
-  vim.diagnostic.config(config)
-end
-
-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", "<leader>dn", "<cmd>lua vim.diagnostic.goto_next()<CR>", opts)
-  map("n", "<leader>dp", "<cmd>lua vim.diagnostic.goto_prev()<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", "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)
-  lsp_keymaps(bufnr)
-end
-
-local custom_init = function(client)
-  client.config.flags = client.config.flags or {}
-  client.config.flags.allow_incremental_sync = true
-end
-
-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 4d8d8011..c08b3a3f 100644
--- a/roles/neovim/files/lua/opdavies/lsp/init.lua
+++ b/roles/neovim/files/lua/opdavies/lsp/init.lua
@@ -1,9 +1,65 @@
-local status_ok, lspconfig = pcall(require, "lspconfig")
-if not status_ok then
+local has_lsp, lspconfig = pcall(require, "lspconfig")
+if not has_lsp then
   return
 end
 
-require("opdavies.lsp.handlers").setup()
+local nvim_status = require "lsp-status"
+
+local imap = require "opdavies.keymap".imap
+local nmap = require "opdavies.keymap".nmap
+
+local buf_nnoremap = function(opts)
+  opts.buffer = 0
+  nmap(opts)
+end
+
+local buf_inoremap = function(opts)
+  opts.buffer = 0
+  imap(opts)
+end
+
+local updated_capabilities = vim.lsp.protocol.make_client_capabilities()
+updated_capabilities = require('cmp_nvim_lsp').update_capabilities(updated_capabilities)
+
+local custom_init = function(client)
+  client.config.flags = client.config.flags or {}
+  client.config.flags.allow_incremental_sync = true
+end
+
+local custom_attach = function(client)
+  local filetype = vim.api.nvim_buf_get_option(0, "filetype")
+
+  nvim_status.on_attach(client)
+
+  -- Keymaps
+  buf_inoremap { "<c-s>", vim.lsp.buf.signature_help }
+
+  buf_nnoremap { "<space>cr", vim.lsp.buf.rename }
+  -- telescope_mapper("<space>ca", "lsp_code_actions", nil, true)
+
+  buf_nnoremap { "gd", vim.lsp.buf.definition }
+  buf_nnoremap { "gD", vim.lsp.buf.declaration }
+  buf_nnoremap { "gT", vim.lsp.buf.type_definition }
+
+  -- buf_nnoremap { "<space>gI", handlers.implementation }
+  buf_nnoremap { "<space>lr", "<cmd>lua R('tj.lsp.codelens').run()<CR>" }
+  buf_nnoremap { "<space>rr", "LspRestart" }
+
+  if filetype ~= "lua" then
+    buf_nnoremap { "K", vim.lsp.buf.hover }
+  end
+
+  -- Set autocommands conditional on server_capabilities
+  if client.resolved_capabilities.document_highlight then
+    vim.cmd [[
+      augroup lsp_document_highlight
+        autocmd! * <buffer>
+        autocmd CursorHold <buffer> lua vim.lsp.buf.document_highlight()
+        autocmd CursorMoved <buffer> lua vim.lsp.buf.clear_references()
+      augroup END
+    ]]
+  end
+end
 
 local servers = {
   ansiblels = true,
@@ -16,14 +72,6 @@ local servers = {
 
   intelephense = {
     filetypes = { "php", "module", "test", "inc" },
-
-    on_attach = function(client)
-      -- Disable document formatting as I use different coding styles per
-      -- framework.
-      -- TODO: remove if editorconfig or something can format based on project.
-      client.resolved_capabilities.document_formatting = false
-      client.resolved_capabilities.document_range_formatting = false
-    end,
   },
 
   sumneko_lua = {
@@ -31,18 +79,37 @@ local servers = {
       Lua = {
         diagnostics = {
           globals = { "vim" },
-        },
-      },
-    },
+        }
+      }
+    }
   },
 
   tailwindcss = {
     filetypes = { "html", "html.twig" },
-  },
+  }
 }
 
-for server, config in pairs(servers) do
-  require("opdavies.lsp.handlers").setup_server(server, config, lspconfig)
+local setup_server = function(server, config)
+  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 = nil,
+    },
+  }, config)
+
+  lspconfig[server].setup(config)
 end
 
-require "opdavies.lsp.null-ls"
+for server, config in pairs(servers) do
+  setup_server(server, config)
+end
diff --git a/roles/neovim/files/lua/opdavies/options.lua b/roles/neovim/files/lua/opdavies/options.lua
index c711c3f6..6101f1d8 100644
--- a/roles/neovim/files/lua/opdavies/options.lua
+++ b/roles/neovim/files/lua/opdavies/options.lua
@@ -71,7 +71,7 @@ local function set_vim_o()
     cursorline = true,
     expandtab = true,
     foldlevel = 1,
-    foldlevelstart = 1,
+    foldlevelstart = 99,
     foldmethod = "indent",
     formatoptions = "lm",
     linebreak = true,