LSP Debugging
LSP issues are the most common source of frustration in a Neovim setup. This lesson provides a systematic debugging approach.
Step 1: Check Basic Health
:checkhealth lsp
This shows:
- Active clients
- Any error messages from LSP initialization
- Provider status (Node, Python, etc.)
Step 2: Verify LSP Attachment
:LspInfo
Shows which servers are attached to the current buffer. If it says "No clients attached" — read on.
Step 3: Check Filetype Detection
LSP servers attach based on filetype, not filename:
:set filetype? → shows current filetype
If it shows filetype= (empty) or the wrong type:
:set filetype=python → manually set it
Add an autocmd to fix it permanently:
vim.api.nvim_create_autocmd({ "BufRead", "BufNewFile" }, {
pattern = "*.env",
callback = function() vim.bo.filetype = "sh" end,
})
Step 4: Check Root Directory Detection
Most LSPs require a project root directory (where they look for config files). If the root isn't detected, LSP won't start.
:lua print(vim.lsp.buf.list_workspace_folders())
Common root markers:
pyright: looks forpyproject.toml,setup.py,.gitts_ls: looks forpackage.json,tsconfig.jsonlua_ls: looks for.luarc.json,.git
Fix: Create the relevant config file in your project root, or initialize a git repo.
Step 5: Enable LSP Logging
-- Enable debug-level LSP logs
vim.lsp.set_log_level("debug")
-- View logs
:lua vim.cmd("edit " .. vim.lsp.get_log_path())
This is verbose — disable after debugging:
vim.lsp.set_log_level("warn")
Step 6: Check Mason Installation
:Mason → UI showing all installed servers
:MasonLog → installation logs
Verify the server binary is accessible:
# Check if server is in PATH after Mason installs
which lua-language-server
which pyright-langserver
Mason installs to ~/.local/share/nvim/mason/bin/. Add to PATH if needed:
export PATH="$HOME/.local/share/nvim/mason/bin:$PATH"
Common LSP Scenarios
Intelephense Not Finding WordPress Functions
- Ensure
stubs = { "wordpress" }is in lspconfig settings - Install WordPress stubs:
composer require --dev php-stubs/wordpress-stubs - Restart LSP:
:LspRestart
ts_ls Too Many Errors for Old JS Codebase
lspconfig.ts_ls.setup({
settings = {
typescript = { diagnostics = { ignoredCodes = { 7006, 7016 } } },
javascript = { diagnostics = { ignoredCodes = { 7006, 7016 } } },
},
})
Formatter Uses Wrong Server
-- Specify which LSP handles formatting
vim.lsp.buf.format({
filter = function(client)
return client.name == "null-ls" -- only null-ls formats
end,
})
Restarting LSP
:LspStop → stop all LSP clients
:LspStart → restart LSP for current filetype
:LspRestart → stop + start