LSP Configuration¶
Detailed configuration options for the Language Server Protocol.
Basic LSP Setup¶
LSP is configured in lua/lsp/lsp.lua. The file sets up:
Zuban (Python language server)
Capabilities
Diagnostics
Keybindings
The configuration is initialized in lua/lsp/init.lua.
Zuban Configuration¶
Zuban settings in lua/lsp/lsp.lua:
lsp.pyright.setup({
capabilities = capabilities,
on_attach = on_attach,
settings = {
python = {
analysis = {
-- Configuration here
}
}
}
})
Key Settings¶
Python Path:
Specify which Python interpreter to use:
settings = {
python = {
pythonPath = os.getenv('HOME') .. '/.virtualenvs/nvim/bin/python',
}
}
By default, LSP auto-detects the virtual environment.
Type Checking:
Control how strict type checking is:
analysis = {
typeCheckingMode = "basic", -- "off", "basic", "strict"
}
Diagnostics Settings:
Global diagnostic configuration:
vim.diagnostic.config({
virtual_text = true, -- Show errors inline
signs = true, -- Show signs in gutter
underline = true, -- Underline errors
update_in_insert = false, -- Don't update while typing
severity_sort = true, -- Sort by severity
})
Diagnostic Levels¶
LSP shows different levels of issues:
Error - Code that won’t run
Warning - Likely issues
Info - Informational
Hint - Suggestions
Filter which to show:
vim.diagnostic.config({
severity = {
min = vim.diagnostic.severity.WARNING, -- Hide hints
}
})
LSP Completion Setup¶
Code completion settings:
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities.textDocument.completion.completionItem.snippetSupport = true
Enables:
Snippet completion
Multi-line completions
Automatic parameter insertion
on_attach Hook¶
The on_attach function runs when LSP connects:
local function on_attach(client, bufnr)
-- Set up keybindings here
-- Customize per-buffer settings
end
Use this to:
Set keybindings (already done in which-key.lua)
Disable features per buffer
Configure inlay hints
Set up format-on-save
Example: Enable inlay hints:
function on_attach(client, bufnr)
if client.server_capabilities.inlayHintProvider then
vim.lsp.inlay_hint.enable(true, { bufnr })
end
end
Multiple Language Servers¶
Add support for other languages:
Go:
lsp.gopls.setup({
capabilities = capabilities,
on_attach = on_attach,
})
Rust:
lsp.rust_analyzer.setup({
capabilities = capabilities,
on_attach = on_attach,
})
TypeScript:
lsp.tsserver.setup({
capabilities = capabilities,
on_attach = on_attach,
})
JavaScript:
lsp.eslint.setup({
capabilities = capabilities,
on_attach = on_attach,
})
Common LSP Capabilities¶
Capabilities define what features LSP can use:
local capabilities = vim.lsp.protocol.make_client_capabilities()
-- Code completion
capabilities.textDocument.completion.completionItem.snippetSupport = true
-- Folding
capabilities.textDocument.foldingRange = {
dynamicRegistration = false,
lineFoldingOnly = true,
}
Advanced Features¶
Code Lens (run tests from editor):
capabilities.textDocument.codeLens = {}
Inlay Hints (type annotations):
capabilities.inlayHint = {}
Semantic Tokens (advanced highlighting):
capabilities.textDocument.semanticTokens = {}
Diagnostics Configuration¶
Control how diagnostics display:
vim.diagnostic.config({
-- Appearance
virtual_text = {
prefix = "●", -- Use a symbol
spacing = 4,
},
-- Behavior
update_in_insert = false,
underline = true,
signs = true,
-- Sorting
severity_sort = true,
})
Diagnostic Keybindings¶
Standard keybindings (in which-key.lua):
wk.add({
{ "]d", vim.diagnostic.goto_next, desc = "Next diagnostic" },
{ "[d", vim.diagnostic.goto_prev, desc = "Prev diagnostic" },
{ "<leader>d", function() vim.diagnostic.toggle() end, desc = "Toggle diagnostics" },
})
Hover Configuration¶
Customize hover information:
-- In on_attach
vim.lsp.buf.hover() -- Show on 'K'
Hover shows:
Documentation
Type information
Signature
Source location
LSP Formatting¶
Format code using LSP:
vim.lsp.buf.format({ async = true })
Or integrate with darker:
-- In autocmds.lua
vim.api.nvim_create_autocmd("BufWritePre", {
pattern = "*.py",
callback = function()
require('darker').format()
end
})
Workspace Folders¶
LSP can track multiple projects:
lsp.add_workspace_folder(vim.fn.getcwd())
Useful for monorepos and multi-project setups.
Debugging LSP Issues¶
Enable logging:
vim.lsp.set_log_level("debug")
View logs:
tail ~/.local/share/nvim/lsp.log
Check status:
:LspInfo
Shows:
Active servers
Capabilities
Configuration
Restart LSP:
:LspRestart
Disabling LSP Features¶
Disable specific features:
-- Disable semantic highlighting
client.server_capabilities.semanticTokensProvider = nil
-- Disable code lens
client.server_capabilities.codeLensProvider = false
Performance Tuning¶
Limit document sync:
-- Sync after delays, not on every keystroke
settings = {
textDocumentSync = 2, -- Incremental
}
Exclude large files:
function on_attach(client, bufnr)
if vim.fn.getfsize(vim.fn.bufname(bufnr)) > 1000000 then
client.stop() -- Don't analyze huge files
end
end
Lazy start:
if vim.fn.exists(':LspStart') == 2 then
vim.cmd.LspStart()
end
Server Settings Reference¶
For Zuban-specific settings, see:
~/.virtualenvs/nvim/bin/pip show zuban
Common settings:
typeCheckingMode- “off”, “basic”, “strict”diagnosticMode- What to reportincludeOptionalDependencies- Type check optional deps
Server-specific Documentation¶
Each language server has its own documentation:
rust-analyzer: https://rust-analyzer.github.io/
tsserver: https://github.com/Microsoft/TypeScript
Testing LSP Configuration¶
After changes:
Restart LSP:
:LspRestartOpen a Python file
Check status:
:LspInfoVerify features work: - Hover with
K- Go to definition withgd- Completions with<C-x><C-o>Check diagnostics
Troubleshooting LSP¶
LSP won’t start:
Check Python path:
:LspInfoVerify Zuban installed:
pip list | grep zubanCheck logs:
:LspLog
Completions not working:
LSP may be analyzing: Wait a moment
Check capabilities:
:LspInfoRestart:
:LspRestart
Slow performance:
Check file size - huge files slow LSP
Disable unnecessary checks
Increase debounce time
Profile with
:LspLog
Wrong diagnostics:
Check type checking mode
Configure exclusions
Verify Python path
See Troubleshooting for more solutions.
Summary¶
LSP configuration is powerful. Key points:
Zuban is the Python server
Configure in
lua/lsp/lsp.luaSet keybindings in
which-key.luaUse diagnostics config for appearance
Add servers for other languages
Tune performance for your workflow