coc.nvim is a powerful autocompletion engine for Vim and Neovim, built on the Language Server Protocol (LSP).
Here’s how you can configure coc.nvim to leverage LSP for a richer coding experience.
First, ensure you have a package manager installed for Vim/Neovim. vim-plug is a popular choice. Add coc.nvim to your init.vim (or init.lua if you’re using Neovim):
" For vim-plug
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Then, run :PlugInstall in Vim.
Next, you need to install language servers for the languages you use. coc.nvim has a built-in command for this:
:CocInstall coc-json coc-tsserver coc-python
This command installs the language servers for JSON, TypeScript/JavaScript, and Python. You can install servers for many other languages similarly. If you’re unsure of the package name, :CocList extensions will show you available extensions.
Now, let’s configure some basic coc.nvim settings in your init.vim:
" Use tab for trigger completion and navigate through completion suggestions
inoremap <expr> <TAB> pumvisible() ? "\<C-n>" : "\<TAB>"
inoremap <expr> <S-TAB> pumvisible() ? "\<C-p>" : "\<S-TAB>"
" Use <CR> to confirm completion
inoremap <expr> <CR> pumvisible() ? coc#_select_confirm() : "\<CR>"
" GoTo definition
nmap <silent> gd <Plug>(coc-definition)
" Find references
nmap <silent> gr <Plug>(coc-references)
" Show documentation
nmap <silent> K <Plug>(coc-doc)
" Show hover information
autocmd CursorHold * silentcall CocActionAsync('showHover')
These settings map common keybindings:
<TAB>and<S-TAB>cycle through suggestions when the completion menu (pumvisible()) is active, and insert a tab otherwise.<CR>(Enter) accepts the selected completion.gdjumps to the definition of the symbol under the cursor.grfinds all references to the symbol.Kdisplays documentation for the symbol.CursorHoldtriggers hover information after a short pause.
After adding these settings and restarting Vim, you should see autocompletion suggestions as you type in files for which you’ve installed language servers. For example, in a JavaScript file with coc-tsserver installed, typing console. will bring up a list of available methods and properties.
Consider a simple TypeScript file:
function greet(name: string): string {
return `Hello, ${name}!`;
}
const message = greet("World");
console.log(message);
As you type greet(", coc.nvim will suggest "World" (if configured for string suggestions) and provide the function signature (name: string): string. Typing console. will show log. If you place your cursor on greet and press gd, you’ll jump directly to its definition. Pressing gr on greet will highlight all usages of the function.
The power of LSP lies in its standardization. Instead of each editor/IDE needing to build custom integrations for every language, they can speak the LSP. The language server runs as a separate process, providing features like completion, diagnostics, go-to-definition, and refactoring to any LSP-compliant client, like coc.nvim.
coc.nvim itself is highly configurable. You can customize completion behavior, diagnostic display, formatting, and much more through its g:coc_config dictionary. For instance, to enable automatic formatting on save:
let g:coc_config = {
\ 'formatOnSaveFiletypes': ['javascript', 'typescript', 'python', 'json'],
\ 'diagnostic.enable': v:true,
\ 'snippets.enable': v:true,
\ 'lsp.documentSyncKind': 'incremental'
\}
This configuration enables formatting on save for specified file types, ensures diagnostics are displayed, enables snippet support, and sets the LSP document synchronization mode to incremental, which is generally more efficient as it only sends changes rather than the entire file.
One subtle but incredibly useful feature is coc-diagnostic-trouble. If you install it (:CocInstall coc-diagnostic-trouble), you can then use :CocTrouble to get a navigable list of all diagnostics (errors, warnings, info) in your project. This is a game-changer for quickly addressing issues across multiple files. You can filter these diagnostics by severity or file path directly within the :CocTrouble buffer.
The next step in mastering coc.nvim is understanding its rich set of asynchronous actions, accessible via :CocAction and :CocActionAsync, which allow for complex refactoring and code manipulation.