LSP (Language Server Protocol)

For years, the biggest argument against terminal-based editors was that they couldn't match the intelligence of a full IDE. The Language Server Protocol changed that equation entirely. By connecting Neovim to the same language servers that power VS Code and other editors, you get go-to-definition, real-time diagnostics, refactoring, and more — without sacrificing the speed and flexibility you love about Vim. LSP is, without exaggeration, one of Neovim's killer features.

What you'll learn in this chapter:

  • Understand what the Language Server Protocol is and how it connects Neovim to language servers

  • Set up Mason, mason-lspconfig, and nvim-lspconfig for automatic server management

  • Configure LSP keymaps for go-to-definition, hover, references, rename, and code actions

  • Customize diagnostics display and set up format-on-save

  • Add linting support beyond what LSP provides

What is LSP?

LSP is a protocol created by Microsoft that standardizes the communication between an editor and a language server. Instead of each editor implementing language support from scratch, they all talk to the same language servers.

┌──────────┐         ┌──────────────────┐
│  Neovim  │ ◄─LSP─► │  Language Server  │
│ (client) │         │  (pyright, gopls, │
│          │         │   tsserver, etc.) │
└──────────┘         └──────────────────┘

Key LSP Features

  • Go to definition (gd) — jump to where a function/variable is defined

  • Hover documentation (K) — show docs for the symbol under cursor

  • Find references (gr) — see all usages of a symbol

  • Rename (<leader>rn) — rename a symbol across the project

  • Code actions (<leader>ca) — quick fixes, refactoring suggestions

  • Diagnostics — inline errors and warnings

  • Formatting — auto-format code on save

  • Signature help — show function parameters as you type

Setting Up LSP

You need three components:

  1. mason.nvim — installs language servers automatically

  2. mason-lspconfig.nvim — bridges Mason and lspconfig

  3. nvim-lspconfig — configures language servers

Plugin Spec

Diagnostics Configuration

Customize how diagnostics (errors, warnings) appear:

Formatting

Format on Save

For more control over formatting, use conform.nvimarrow-up-right:

Linting

For linting beyond what LSP provides, use nvim-lintarrow-up-right:

Common Language Servers

Language
Server
Install with Mason

Lua

lua_ls

:MasonInstall lua-language-server

Python

pyright or basedpyright

:MasonInstall pyright

TypeScript

ts_ls

:MasonInstall typescript-language-server

Go

gopls

:MasonInstall gopls

Rust

rust_analyzer

:MasonInstall rust-analyzer

C/C++

clangd

:MasonInstall clangd

Java

jdtls

:MasonInstall jdtls

HTML/CSS

html, cssls

:MasonInstall html-lsp css-lsp

JSON

jsonls

:MasonInstall json-lsp

YAML

yamlls

:MasonInstall yaml-language-server

Bash

bashls

:MasonInstall bash-language-server

Tip: Run :Mason to open the Mason UI and browse/install available servers.

Note: LSP provides language intelligence, while Treesitter (see Chapter 14: Treesitter) provides syntax-aware highlighting and text objects. They complement each other and are best used together.

Summary

The Language Server Protocol gives Neovim the same code intelligence features found in full IDEs -- go-to-definition, hover documentation, find references, rename, and real-time diagnostics -- all powered by external language servers. With Mason handling server installation and lspconfig handling configuration, setting up LSP is straightforward and reproducible across machines.

Key takeaways:

  • LSP is a protocol, not a plugin. Neovim acts as the client; language servers (pyright, gopls, lua_ls, etc.) do the heavy lifting.

  • Mason + mason-lspconfig + nvim-lspconfig is the standard three-part setup for managing and configuring language servers.

  • LSP keymaps should be attached via the LspAttach autocmd so they only activate in buffers with an active language server.

  • Diagnostics, formatting (with conform.nvim), and linting (with nvim-lint) can all be customized to fit your workflow.

Exercises

  1. Install a language server with Mason -- Open Neovim and run :Mason to browse available servers. Install the language server for a language you use (e.g., lua-language-server for Lua). Verify it appears in :Mason as installed.

  2. Verify LSP is working -- Open a source file in a language you have configured (e.g., a .lua or .py file). Use gd to go to a function definition, K to view hover documentation, and gr to find references.

  3. Customize diagnostic display -- Configure diagnostics to use rounded borders on floating windows, show the prefix for virtual text, and sort by severity. Verify the changes by introducing a deliberate error in a source file.

  4. Set up format on save -- Configure conform.nvim to automatically format your code on save. Add formatters for at least two languages you work with.

  5. Add a new language server -- Pick a language not yet in your configuration (e.g., Go, Rust, or TypeScript). Install its server with Mason, add it to your ensure_installed list, and call lspconfig.<server>.setup(). Verify with :LspInfo.

Last updated

Was this helpful?