Skip to content
Demon edited this page Mar 17, 2024 · 144 revisions

Here are some common problems that you may need to understand when working with coc.nvim.

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

We can implement this requirement by customizing the configuration file (.vimrc or coc.vim which is in the directory coc.nvim/plugin/) and writing a vim script function to help to jump out from within pairs of symbols as intelligently as using the IDE's <TAB> key, and without switching vim's mode.

Here are the steps:

  1. Use the command vim in any directory to get to the welcome screen of vim.
  2. In the welcome screen, we use :h coc-completioin-example to open the coc.txt document, and will come directly to the completion example section, which provides more configuration examples than those in README.md.
  3. Scrolling down, we can see this configuration suggestion where he tells us how to use the <TAB> key to trigger completion, completion confirm, snippet expand 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#_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. Let's copy this code above and paste it into the configuration file mentioned above(i.e. .vimrc or coc.vim/plugin/coc.vim).
  2. In the end, we just need to make some changes to this code and add a script function NextCharIsPair(), and this is all that's left after the changes:
" Map <tab> for trigger completion, completion confirm, snippet expand and jump, jump outside closing bracket or other pairs of symbols like VSCode
inoremap <silent><expr> <Tab>
  \ coc#pum#visible() ? coc#_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. that the coc-snippets extension is required for this to work, which can be installed using the commands :CocInstall coc-snippets.

<tab> not working well with copilot.vim

copilot.vim remaps your <tab>, it checks pumvisible but not coc#pum#visible, so it not work well with the custom popup menu. You can disable the overwrite and define the <tab> to meet your need, like:

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's not 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 not working after changing colorscheme

Most colorschemes clear existing highlights when loaded, 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

And you have to use nested autocommand to make your autocommand fire when using the ColorScheme event:

autocmd vimenter * ++nested colorscheme gruvbox

The selection highlight does not look good

CocMenuSel is used for highlight select item, the highlight group uses background color from PmenuSel. However, many color schemes not considered other highlights inside it.

You can change the highlight group by:

hi CocMenuSel ctermbg=237 guibg=#13354A

in your vimrc, to survive after color scheme change, use:

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

Can't get keywords completion items from other buffers

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

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

Environment node doesn't meet the requirement.

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

How could I use omnifunc option to trigger completion of coc.nvim?

You can't, there's no such function provided for omnifunc option, because vim's omnifunc always block and LSP features like triggerCharacters and incomplete response can't work.

If you want to manually trigger completion 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 instead:

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

Vim freezes sometimes.

  • 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 is not saved to disk. This is because they are only tested on VS Code which always creates a file before creating a buffer.

Save the buffer to disk and restart coc.nvim server using :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 in settings file to enable refresh when entering insert mode.

Diagnostic signs not shown.

If there are other signs that have a higher offset, the signs that coc.nvim shows won't be visible. You can change the offset of coc.nvim's signs by add "diagnostic.signOffset": 9999999 to your coc-settings.json to make it higher priority. The default value is 1000. You can also change the signcolumn option (available with latest version of Neovim): set signcolumn=auto:2.

Sometimes no completion triggered after trigger character is typed.

It takes a little bit of time for language servers to detect that you have modified a file and display the appropriate completions. You can change the wait time for language server to finish the document change process before completion by setting suggest.triggerCompletionWait in your coc-settings.json, its default value is 50(milliseconds).

My keymap is not working.

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

How can I profile vim?

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

How can I profile coc.nvim?

To get the communication between Vim and coc.nvim

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

How to get log of coc.nvim?

Enable debug mode for coc.nvim by environment variable:

let $NVIM_COC_LOG_LEVEL = 'trace'

Open log file by command:

:CocOpenLog

How to show documentation of symbol under cursor(cursor hover)?

This is done by the doHover action. Configure a mapping like, e.g.:

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

Cursor disappears after exiting CocList

Possible bug with the guicursor option in your terminal, you can disable transparent cursor by

let g:coc_disable_transparent_cursor = 1

in your .vimrc.

Floating window position is wrong after scroll the screen.

It's expected since the float windows/popups are absolutely positioned.

How can I disable floating windows?

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

Highlight of background seems wrong with floating window.

The default highlight group linked by CocFloating could have reverse attribute, you will have colored background for some texts on that case, define your own CocFloating highlight group on that case.

hi link CocFloating Normal

How to scroll float window?

Checkout :h coc#float#has_scroll()

How to open link in float window?

Focus the window by <C-w>w if it's focusable on Neovim and invoke :call CocAction('openlink')

REPL

Clone this wiki locally