Setup coc.nvim
Get completion, diagnostics, and code navigation working in three focused steps.
Check your environment
You need Node.js and either a supported Neovim or Vim.
node --versionnvim --versionvim --versionInstall with one command
Choose your editor, review the command, then run it in a terminal.
Quick Script InstallRecommended
Uses the selected editor's native pack mechanism. Run again anytime to update.
Review what it runs before executing: view installer source.
curl -fsSL https://cocnvim.com/install-coc.sh | bash -s -- --editor=nvim
The script checks Node.js and Neovim, detects another coc.nvim installation, then shows every planned path before confirmation. It installs to ${XDG_DATA_HOME:-~/.local/share}/nvim/site/pack/coc/opt/coc.nvim and the Neovim init file and preserves an existing native-pack copy as .backup-*. It adds one idempotent packadd coc.nvim entry when the config does not already load coc.nvim. Use --no-config / -NoConfig to leave config unchanged.
Prefer a plugin manager, native package, or source build? See all installation methods.
Enable the essentials
Select language support on the left and copy the generated editor setup.
Language support
0 selectedOptional. Selected extensions are installed automatically when coc.nvim starts.
| 1 | -- Add to ~/.config/nvim/init.lua |
| 2 | vim.g.coc_global_extensions = { } |
| 3 | |
| 4 | vim.opt.backup = false |
| 5 | vim.opt.writebackup = false |
| 6 | vim.opt.updatetime = 300 |
| 7 | vim.opt.signcolumn = 'yes' |
| 8 | vim.opt.laststatus = 2 |
| 9 | |
| 10 | -- Show coc.nvim status, including extension installation progress |
| 11 | vim.opt.statusline:prepend('%{coc#status()}') |
| 12 | |
| 13 | local keyset = vim.keymap.set |
| 14 | function _G.check_back_space() |
| 15 | local col = vim.fn.col('.') - 1 |
| 16 | return col == 0 or vim.fn.getline('.'):sub(col, col):match('%s') ~= nil |
| 17 | end |
| 18 | |
| 19 | -- Trigger completion with Tab and navigate the completion menu |
| 20 | local opts = { silent = true, noremap = true, expr = true, replace_keycodes = false } |
| 21 | keyset('i', '<TAB>', 'coc#pum#visible() ? coc#pum#next(1) : v:lua.check_back_space() ? "<TAB>" : coc#refresh()', opts) |
| 22 | keyset('i', '<S-TAB>', [[coc#pum#visible() ? coc#pum#prev(1) : "\<C-h>"]], opts) |
| 23 | keyset('i', '<CR>', 'coc#pum#visible() ? coc#pum#confirm() : "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"', { silent = true, expr = true }) |
| 24 | |
| 25 | -- Diagnostics and code navigation |
| 26 | keyset('n', '[g', '<Plug>(coc-diagnostic-prev)', { silent = true }) |
| 27 | keyset('n', ']g', '<Plug>(coc-diagnostic-next)', { silent = true }) |
| 28 | keyset('n', 'gd', '<Plug>(coc-definition)', { silent = true }) |
| 29 | keyset('n', 'gy', '<Plug>(coc-type-definition)', { silent = true }) |
| 30 | keyset('n', 'gi', '<Plug>(coc-implementation)', { silent = true }) |
| 31 | keyset('n', 'gr', '<Plug>(coc-references)', { silent = true }) |
| 32 | keyset('n', '<leader>rn', '<Plug>(coc-rename)', { silent = true }) |
The extension list is optional. coc.nvim provides the client; language features become available after an extension or manually configured server starts.
Restart your editor and try it
Open a file for a selected language, then run :CocInfo to confirm coc.nvim and its language service are running.