Always be programming

Intelligent autocompletion in Vim

May 14, 2019

I’ve been using Vim as my main editor since University and I’ve spent countless hours customizing it to be exactly like I want it. One thing that I probably spent more time on than anything else is autocompletion. I love working with Vim but it seemed like I could never get the suggestions to be comparable to the likes of VSCode and Webstorm.

Over the years I tried YouCompleteMe, deoplete.nvim, LanguageClient-neovim but I could not find anything that was robust, provided good suggestions and supported all programming languages that I a work with on a regular basis (Javascript/Typescript, Go and Python). That was until recently when I found Coc.nvim 🥂 Coc autocompletion example It implements full language server support and extension features of VSCode allowing an awesome programming experience. Coc offers out of the box support for javascript/typescript, json, html, css, vue, php, java, ruby, rust, yaml, python as well as third party support for many other languages including go and dart.

Setup

Coc supports vim >= 8.1 and neovim >= 0.3.1 but if you are using neovim it’s highly recommended to install version 0.4 to be able to take advantage of the new floating windows.

Installing neovim 0.4 on OSX with brew

brew install --HEAD neovim

Coc configuration

My configuration is pretty standard and follows the setup instructions in the project documentation.

  " Coc.nvim
Plug 'neoclide/coc.nvim',
  {'tag': '*', 'do': { -> coc#util#install()}}

let g:coc_global_extensions = [
  'coc-emoji', 'coc-eslint', 'coc-prettier',
  'coc-tsserver', 'coc-tslint', 'coc-tslint-plugin',
  'coc-css', 'coc-json', 'coc-pyls', 'coc-yaml'
]

" Better display for messages
set cmdheight=2
" Smaller updatetime for CursorHold & CursorHoldI
set updatetime=300
" don't give |ins-completion-menu| messages.
set shortmess+=c
" always show signcolumns
set signcolumn=yes

" Use `lp` and `ln` for navigate diagnostics
nmap <silent> <leader>lp <Plug>(coc-diagnostic-prev)
nmap <silent> <leader>ln <Plug>(coc-diagnostic-next)

" Remap keys for gotos
nmap <silent> <leader>ld <Plug>(coc-definition)
nmap <silent> <leader>lt <Plug>(coc-type-definition)
nmap <silent> <leader>li <Plug>(coc-implementation)
nmap <silent> <leader>lf <Plug>(coc-references)

" Remap for rename current word
nmap <leader>lr <Plug>(coc-rename)

" Use K for show documentation in preview window
nnoremap <silent> K :call <SID>show_documentation()<CR>

function! s:show_documentation()
  if &filetype == 'vim'
    execute 'h '.expand('<cword>')
  else
    call CocAction('doHover')
  endif
endfunction

" Highlight symbol under cursor on CursorHold
autocmd CursorHold * silent call CocActionAsync('highlight')

Coc is built on an extension based architecture allowing you to install exactly the features that you require from the built in extension manager with the :CocInstall command, you can also define them in your .vimrc file like me and then they will be automatically installed on startup. As you can see I currently use coc-emoji, coc-eslint, coc-prettier, coc-tsserver, coc-tslint, coc-tslint-plugin, coc-css, coc-json, coc-pyls and coc-yaml but there are plenty more to choose from. (See docs for more information)

If you like me have been jealous of the awesome IntelliSense in VSCode but don’t want to switch to another editor then Coc gives you a way to have your 🍰 and 🍴 it too. Try it out, you will not regret it! Lastly, if you want more details on my full Vim setup (countless hours have been spent fine tuning it 🏆) then you can check out my .vimrc.


Kim Persson

Written by Kim Persson (kimpers) a senior full-stack engineer with a great passion for programming, decentralization and blockchain.