Skip to content
Qiming Zhao edited this page Aug 3, 2026 · 146 revisions

Here are some common problems you may encounter when working with coc.nvim.

How to use the <TAB> key in insert mode to jump directly outside pairs of symbols like (), "", ''?

You can implement this by customizing the configuration file (.vimrc, or coc.vim in the coc.nvim/plugin/ directory) and writing a vim script function that jumps out of pairs of symbols as intelligently as the IDE's <TAB> key, without switching vim's mode.

Here are the steps:

  1. Run vim in any directory to get to vim's welcome screen.
  2. On the welcome screen, run :h coc-completion-example to open the coc.txt document. This takes you directly to the completion example section, which provides more configuration examples than README.md.
  3. Scrolling down, you can see this configuration suggestion, which shows how to use the <TAB> key to trigger completion, confirm completion, expand snippets, and jump like VSCode:
Map <tab> for trigger completion, completion confirm, snippet expand and jump
like VSCode:

  inoremap <silent><expr> <TAB>
    \ coc#pum#visible() ? coc#pum#select_confirm() :
    \ coc#expandableOrJumpable() ?
    \ "\<C-r>=coc#rpc#request('doKeymap', ['snippets-expand-jump',''])\<CR>" :
    \ CheckBackspace() ? "\<TAB>" :
    \ coc#refresh()

  function! CheckBackspace() abort
    let col = col('.') - 1
    return !col || getline('.')[col - 1]  =~# '\s'
  endfunction

  let g:coc_snippet_next = '<tab>'
  1. Copy the code above and paste it into the configuration file mentioned earlier (i.e. .vimrc or coc.nvim/plugin/coc.vim).
  2. Finally, make some changes to this code and add a script function NextCharIsPair(). This is the result:
" Map <tab> to trigger completion, confirm completion, expand and jump snippets, and jump out of closing brackets or other pairs of symbols like VSCode
inoremap <silent><expr> <Tab>
  \ coc#pum#visible() ? coc#pum#select_confirm() :
  \ coc#expandableOrJumpable() ?
  \ "\<C-r>=coc#rpc#request('doKeymap', ['snippets-expand-jump',''])\<CR>" :
  \ NextCharIsPair() ? "\<Right>" :
  \ CheckBackspace() ? "\<Tab>" :
  \ coc#refresh()

function! CheckBackspace() abort
  let col = col('.') - 1 
  return !col || getline('.')[col - 1]  =~# '\s'
endfunction

function! NextCharIsPair() abort
  let col = col('.') - 1 
  let l:next_char = getline('.')[col]
  return l:next_char =~# ')\|]\|}\|>\|''\|"\|`'
endfunction

let g:coc_snippet_next = '<tab>'

N.B. This requires the coc-snippets extension, which can be installed with :CocInstall coc-snippets.

<tab> not working well with copilot.vim

copilot.vim remaps <tab> and checks pumvisible instead of coc#pum#visible, so it doesn't work well with the custom popup menu. You can disable the overwrite and define <tab> to suit your needs, like this:

let g:copilot_no_tab_map = v:true
inoremap <silent><expr> <TAB>
      \ coc#pum#visible() ? coc#pum#next(1):
      \ exists('b:_copilot.suggestions') ? copilot#Accept("\<CR>") :
      \ CheckBackSpace() ? "\<Tab>" :
      \ coc#refresh()

Use <C-e> to cancel the popup menu (if it isn't remapped).

Unexpected diagnostics when using easymotion

Use an autocommand like:

autocmd User EasyMotionPromptBegin :let b:coc_diagnostic_disable = 1
autocmd User EasyMotionPromptEnd :let b:coc_diagnostic_disable = 0

Some highlight groups don't work after changing the colorscheme

Most colorschemes clear existing highlights when loaded, so make sure to set your highlights with an autocommand that executes on a ColorScheme event:

autocmd ColorScheme * call Highlight()

function! Highlight() abort
  hi Conceal ctermfg=239 guifg=#504945
  hi CocSearch ctermfg=12 guifg=#18A3FF
endfunction

You also have to use a nested autocommand to make your autocommand fire on the ColorScheme event:

autocmd vimenter * ++nested colorscheme gruvbox

The selection highlight does not look good

CocMenuSel is used to highlight the selected item; the highlight group uses the background color from PmenuSel. However, many color schemes don't consider other highlights inside it.

You can change the highlight group by:

hi CocMenuSel ctermbg=237 guibg=#13354A

in your vimrc. To keep it after a colorscheme change, use:

autocmd ColorScheme * hi CocMenuSel ctermbg=237 guibg=#13354A

Can't get keyword completion items from other buffers

The buffer source only provides keywords from buffers that meet these conditions:

  • Use the bufloaded() function to check whether a buffer is loaded.
  • The buftype option should be empty; check it with :echo getbufvar(bufnr, "&buftype").

Node version doesn't meet the requirements

Use let g:coc_node_path = '/path/to/node' to make coc.nvim use a custom node executable.

How can I use the omnifunc option to trigger coc.nvim completion?

You can't. There's no function provided for the omnifunc option, because vim's omnifunc always blocks and LSP features like triggerCharacters and incomplete responses can't work.

To trigger completion manually, add "suggest.autoTrigger": "none" to your coc-settings.json and bind a trigger key:

  inoremap <silent><expr> <c-space> coc#refresh()

Note that some terminals send <NUL> when you press <c-space>, so you could use this instead:

  inoremap <silent><expr> <NUL> coc#refresh()

Vim sometimes freezes

  • Make sure you have set hidden in your .vimrc.
  • Use CocActionAsync instead of CocAction in your autocommand, except for BufWritePre.
  • Use CocRequestAsync instead of CocRequest when possible.

Language server doesn't work with unsaved buffers

Some language servers don't work when the buffer isn't saved to disk, because they are only tested on VS Code, which always creates a file before creating a buffer.

Save the buffer to disk and restart the coc.nvim server with :CocRestart to make the language server work.

Linting is slow

By default, coc doesn't show diagnostics in Vim's UI when you're in insert mode. Add "diagnostic.refreshOnInsertMode": true to the settings file to enable refreshing when entering insert mode.

Diagnostic signs are not shown

If other signs have a higher priority, the signs shown by coc.nvim won't be visible. You can raise the priority of coc.nvim's signs by adding "diagnostic.signPriority": 9999 to your coc-settings.json (the default value is 10). You can also change the signcolumn option (available in the latest version of Neovim): set signcolumn=auto:2.

Sometimes no completion is triggered after a trigger character is typed

It takes a little time for language servers to detect that you've modified a file and to display the appropriate completions. You can change how long the language server waits to finish the document change process before completion by setting suggest.triggerCompletionWait in your coc-settings.json; its default value is 0 (milliseconds).

My keymap is not working.

Some plugins like UltiSnips and vim-closer remap <tab> or <cr>. You can diagnose keymap-related issues with :verbose imap <tab>.

How can I profile vim?

  • Enter these commands:
    :profile start profile.log
    :profile func *
    :profile file *
  • Reproduce the issue.
  • Run the :profile stop command (Neovim only).
  • Exit vim and open the newly generated profile.log file in your current directory.

How can I profile coc.nvim?

To log the communication between Vim and coc.nvim:

  • Add let g:node_client_debug = 1 in your vimrc.
  • Restart Vim and reproduce the issue.
  • Use :call coc#client#open_log() to open a log file, or use :echo $NODE_CLIENT_LOG_FILE to get the file path of the log.

How to get log of coc.nvim?

Enable debug mode for coc.nvim with an environment variable:

let $NVIM_COC_LOG_LEVEL = 'trace'

Open the log file with the command:

:CocOpenLog

How to show hover documentation for the symbol under the cursor?

This is done by the doHover action. Configure a mapping, for example:

nnoremap <silent> <leader>h :call CocActionAsync('doHover')<cr>

Cursor disappears after exiting CocList

This is a possible bug with the guicursor option in your terminal. You can disable the transparent cursor with:

let g:coc_disable_transparent_cursor = 1

in your .vimrc.

Floating window position is wrong after scrolling the screen

This is expected, since the float windows/popups are absolutely positioned.

How can I disable floating windows?

  • For completion documentation, use "suggest.enableFloat": false in coc-settings.json.
  • For diagnostic messages, use "diagnostic.messageTarget": "echo" in coc-settings.json.
  • For signature help, use "signature.target": "echo" in coc-settings.json.
  • For documentation on hover, use "hover.target": "echo" in coc-settings.json.

Background highlight seems wrong with floating windows

The default highlight group linked to CocFloating may have the reverse attribute, which gives some text a colored background. In that case, define your own CocFloating highlight group.

hi link CocFloating Normal

How to scroll the float window?

Check out :h coc#float#has_scroll().

How to open a link in the float window?

Focus the window with <C-w>w if it's focusable on Neovim, and invoke :call CocAction('openLink').

REPL

Clone this wiki locally