Language servers provide IDE features: autocomplete, diagnostics (error highlighting), go-to-definition, rename, hover docs. Neovim has a built-in LSP client; you install language servers separately.
Neovim's LSP client communicates with language servers (external processes). Each language needs its own server: pyright for Python, clangd for C/C++, eslint for JavaScript, etc.
Server types:
npm install -g pyright, pip install pylsp (common for interpreted languages)Install plugin:
-- ~/.config/nvim/lua/plugins/init.lua { "neovim/nvim-lspconfig", }
Then configure servers in ~/.config/nvim/init.lua:
local lspconfig = require("lspconfig") -- Python lspconfig.pyright.setup({}) -- C/C++ lspconfig.clangd.setup({}) -- JavaScript/TypeScript lspconfig.tsserver.setup({})
Before using a server, install it:
# Python pip install pyright # JavaScript/TypeScript npm install -g typescript-language-server # C/C++ apt install clangd # Linux brew install llvm # macOS
After setup, use vim.lsp functions in keybindings:
vim.keymap.set('n', 'gd', vim.lsp.buf.definition) -- go to definition vim.keymap.set('n', 'gr', vim.lsp.buf.references) -- find references vim.keymap.set('n', 'K', vim.lsp.buf.hover) -- hover info vim.keymap.set('n', '<leader>rn', vim.lsp.buf.rename) -- rename vim.keymap.set('n', '<leader>ca', vim.lsp.buf.code_action) -- code action
LSP shows errors/warnings inline. Check status:
:LspInfo " show LSP status :LspStart " start LSP for current file :LspStop " stop LSP
Jump to diagnostics:
:lua vim.diagnostic.goto_next() " next error :lua vim.diagnostic.goto_prev() " prev error
Map these:
vim.keymap.set('n', '<leader>e', vim.diagnostic.goto_next) vim.keymap.set('n', '<leader>E', vim.diagnostic.goto_prev)
Diagnostics show in sign column and as virtual text. Customize display:
vim.diagnostic.config({ virtual_text = true, underline = true, signs = true, })
LSP sends completion suggestions to nvim-cmp (autocomplete plugin):
{ "hrsh7th/nvim-cmp", dependencies = { "hrsh7th/cmp-nvim-lsp", "L3MON4D3/LuaSnip", }, }
Configure:
local cmp = require("cmp") cmp.setup({ sources = { { name = "nvim_lsp" }, { name = "luasnip" }, }, mapping = cmp.mapping.preset.insert({ ["<C-b>"] = cmp.mapping.scroll_docs(-4), ["<C-f>"] = cmp.mapping.scroll_docs(4), ["<C-Space>"] = cmp.mapping.complete(), ["<CR>"] = cmp.mapping.confirm({ select = true }), }), })
Then <C-Space> triggers autocomplete.
LSP not starting: Check :LspInfo. Missing language server? Install it and add to PATH.
No diagnostics: Server may not be configured. Read server docs and init settings.
Slow autocomplete: Language server may be resource-intensive. Some servers (pylance) need powerful hardware.
Hover not working: Some servers need specific configuration. Check server docs or try hover alternative: :help lsp-hover.
LSP is powerful but needs setup. Start with one language, expand as needed.