I finally was annoyed enough to set up proper code-completion in Vim. This is mostly a highly condensed and simplified version of a great blog post from somebody else: https://octetz.com/posts/vim-as-go-ide
The main difference is that i’m not using Neovim. The reason being that i really like gvim and all the GUI options for Neovim are either bloated Electron abominations or just looking awkward.
Quick setup
Anyway, to replicate my setup you need:
- Vim in at least version 8.0
- The excellent vim-plug installed: https://github.com/junegunn/vim-plug
- Go installed and properly configured (if you care about the Go integration)
Put this in your .vimrc
:
" vim-plug config
call plug#begin('~/.vim/plugged')
Plug 'fatih/vim-go', { 'do': ':GoInstallBinaries', 'for': 'go' }
Plug 'tpope/vim-surround'
Plug 'scrooloose/nerdtree', { 'on': 'NERDTreeToggle' }
Plug 'neoclide/coc.nvim', {'branch': 'release'}
Plug 'sheerun/vim-polyglot'
Plug 'PProvost/vim-ps1'
call plug#end()
Then either open Vim and run :PlugInstall
, or run it via your shell with
vim +PlugInstall
. The result will be the same. You’ll get some progress indicators
and in the end a confirmation that all the wanted plugins are installed.
Explaination of the plugins from above:
- vim-go: Go development plugin (https://github.com/fatih/vim-go)
- vim-surround: nice helper for changing quotes, braces…etc (https://github.com/tpope/vim-surround)
- nerdtree: file browser thingy (https://github.com/scrooloose/nerdtree)
- CoC: code completion engine black magic (https://github.com/neoclide/coc.nvim)
- vim-polyglot: language pack collection (https://github.com/sheerun/vim-polyglot)
- vim-ps1: powershell plugin (yes, some of us have professionally deal with that) (https://github.com/PProvost/vim-ps1)
Install language servers
coc.nvim
enables you to use the very nice concept of language servers (https://en.wikipedia.org/wiki/Language_Server_Protocol).
So to use that, you need to install some of them. On Arch you’d do something like
$ pacman -S bash-language-server python-language-server
go-langserver
can be installed with
$ go get -u github.com/sourcegraph/go-langserver
Configure language servers
To actually configure coc.nvim
to make use of some language servers run :CocConfig
in your Vim.
Then configure it like:
{
"powershell.integratedConsole.showOnStartup": false,
"diagnostic.virtualText": true,
"languageserver": {
"golang": {
"command": "go-langserver",
"filetypes": ["go"],
"initializationOptions": {
"gocodeCompletionEnabled": true,
"diagnosticsEnabled": true,
"lintTool": "golint"
}
}
},
"languageserver": {
"bash": {
"command": "bash-language-server",
"args": ["start"],
"filetypes": ["sh"],
"ignoredRootPaths": ["~"]
}
},
"languageserver": {
"terraform": {
"command": "terraform-lsp",
"filetypes": ["terraform"],
"initializationOptions": {}
}
}
}
And then you want to make sure some coc.nvim
extensions are installed if missing.
You do that with adding this to your .vimrc
:
" automatically install coc extensions if they're missing
let g:coc_global_extensions=[ 'coc-powershell', 'coc-python' , 'coc-yaml']
Overall coc.nvim config
Finally, you want to properly configure coc.nvim
.
Just put this into your .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'
endfunction
" 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>
This seemed to work fine for me. Have fun and enjoy your Vim on steroids :-)