Why a completion engine matters
Native LSP gives you the data: "these are the symbols available here, with these signatures." A completion engine takes that data and presents it as a usable popup — ranking suggestions, expanding snippets, integrating buffer words and file paths, handling tab behavior. Neovim has two strong options in 2026:
- nvim-cmp — the long-standing default. Mature, huge plugin ecosystem, lots of source plugins.
- blink.cmp — newer (2024+), Rust-backed, designed to be faster and simpler. Rapidly catching up on parity. Worth trying if startup-perf matters.
This lesson uses nvim-cmp — it's the safer choice if you're configuring once and forgetting. Migrating to blink.cmp later is straightforward; the spec shape is similar.
What you wire up
- The completion engine itself.
- Sources — LSP, buffer words, file paths, snippets.
- A snippet expander (
LuaSnip). - Key mappings inside the popup (Tab to navigate, Enter to confirm, Esc to dismiss).
- The capabilities object that tells the LSP server what your client supports — this enables snippet completion, auto-imports, etc.
The mental model
Completion is a sorted, filtered, ranked merge of candidates from each source. nvim-cmp queries every source, takes their suggestions, applies your ranking rules, shows the popup. Each source is independent — you can disable buffer words for Markdown files, prioritize LSP in Python files, etc.