Love My Love

Vim Switch YCM to LSP, coc.nvim And Vimgo


Hi there, as the refer article author said, it is 2019, but now, me, 2020.
we use YCM for years, but with the introduction of Language Server Protocol(LSP),
there are new options worth exploring, I tried on OSX and ArchLinux, it’s great for me, maybe it’ll fit you too.


Go’s offical LSP is gopls, pronounced “go please”.


Install vim-go

  1. rm YCM, rm the line in .vimrc and save, then: :PlugClean
  2. Add config:
call plug#begin('~/.vim/plugged')

" < Other Plugins, if they exist >

Plug 'fatih/vim-go'
call plug#end()"
  1. vim +PlugInstall and vim +GoInstallBinaries
  2. vim a go file to verify vim-go working well.

Install coc.nvim

call plug#begin('~/.vim/plugged')

" < Other Plugins, if they exist >

Plug 'fatih/vim-go'
Plug 'neoclide/coc.nvim', {'do': 'yarn install --frozen-lockfile'}
call plug#end()"

Copy the following into .vimrc:

" -------------------------------------------------------------------------------------------------
" coc.nvim default settings
" -------------------------------------------------------------------------------------------------

" if hidden is not set, TextEdit might fail.
set hidden
" 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 tab for trigger completion with characters ahead and navigate.
" Use command ':verbose imap <tab>' to make sure tab is not mapped by other plugin.
inoremap <silent><expr> <TAB>
      \ pumvisible() ? "\<C-n>" :
      \ <SID>check_back_space() ? "\<TAB>" :
      \ coc#refresh()
inoremap <expr><S-TAB> pumvisible() ? "\<C-p>" : "\<C-h>"

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

" Use <c-space> to trigger completion.
inoremap <silent><expr> <c-space> coc#refresh()

" Use `[c` and `]c` to navigate diagnostics
nmap <silent> [c <Plug>(coc-diagnostic-prev)
nmap <silent> ]c <Plug>(coc-diagnostic-next)

" Remap keys for gotos
nmap <silent> gd <Plug>(coc-definition)
nmap <silent> gy <Plug>(coc-type-definition)
nmap <silent> gi <Plug>(coc-implementation)
nmap <silent> gr <Plug>(coc-references)

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

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

" Remap for format selected region
vmap <leader>f  <Plug>(coc-format-selected)
nmap <leader>f  <Plug>(coc-format-selected)
" Show all diagnostics
nnoremap <silent> <space>a  :<C-u>CocList diagnostics<cr>
" Manage extensions
nnoremap <silent> <space>e  :<C-u>CocList extensions<cr>
" Show commands
nnoremap <silent> <space>c  :<C-u>CocList commands<cr>
" Find symbol of current document
nnoremap <silent> <space>o  :<C-u>CocList outline<cr>
" Search workspace symbols
nnoremap <silent> <space>s  :<C-u>CocList -I symbols<cr>
" Do default action for next item.
nnoremap <silent> <space>j  :<C-u>CocNext<CR>
" Do default action for previous item.
nnoremap <silent> <space>k  :<C-u>CocPrev<CR>
" Resume latest coc list
nnoremap <silent> <space>p  :<C-u>CocListResume<CR>

more info about config above: coc.nvim’s recommendations.

copy or modify following to tell vim-go to not map gb as its shortcut for go definition.

" disable vim-go :GoDef short cut (gd)
" this is handled by LanguageClient [LC]
let g:go_def_mapping_enabled = 0

this is disabled to allow coc.vim to do the gd resolution.

OK, save and exit vim

Install coc.nvim: vim +PlugInstall

my output:

yarn install v1.22.4
[1/5] Validating package.json...
[2/5] Resolving packages...
[3/5] Fetching packages...
info fsevents@2.1.3: The platform "linux" is incompatible with this module.
info "fsevents@2.1.3" is an optional dependency and failed compatibility check. Excluding it from installation.
[4/5] Linking dependencies...
warning " > @typescript-eslint/eslint-plugin@2.33.0" has incorrect peer dependency "eslint@^5.0.0 || ^6.0.0".
warning " > @typescript-eslint/eslint-plugin-tslint@2.33.0" has incorrect peer dependency "eslint@^5.0.0 || ^6.0.0".
warning " > @typescript-eslint/eslint-plugin-tslint@2.33.0" has unmet peer dependency "tslint@^5.0.0 || ^6.0.0".
warning " > @typescript-eslint/parser@2.33.0" has incorrect peer dependency "eslint@^5.0.0 || ^6.0.0".
[5/5] Building fresh packages...
warning Your current version of Yarn is out of date. The latest version is "1.22.5", while you're on "1.22.4".
info To upgrade, run the following command:
$ curl --compressed -o- -L | bash
$ npm-run-all clean build
yarn run v1.22.4
$ rimraf lib build
Done in 0.11s.
yarn run v1.22.4
$ tsc -p tsconfig.json
Done in 6.46s.
Done in 37.76s.

Edit the CocConfig: :CocConfig

  "languageserver": {
    "golang": {
      "command": "gopls",
      "rootPatterns": ["go.mod", ".vim/", ".git/", ".hg/"],
      "filetypes": ["go"]

restart vim. ok, me done. what about u?