Today I Learned
Ask or search…
Comment on page

Configuring LSP on NeoVim

Posted on 26 May, 2021
Make sure you have NeoVim version >=0.5.5 installed

Necessary stuff

" For language server configurations
Plug 'neovim/nvim-lspconfig'
For autocompletion choose either of these choices both seems to be equally good
Plug 'nvim-lua/completion-nvim'
Plug 'hrsh7th/nvim-compe'
For the sake of this guide I have chosen nvim-compe

Installing language servers

You would have to manually install the language servers you need.
  1. 1.
    Install language server pack for python (make sure you are running latest pip and Python 3.6+)
    pip install 'python-language-server[all]'
    Another alternative to python-language-server is pyright​
    pip3 install pyright
  2. 2.
    Language server pack for go is maintained by the go team itself. Use go get to install gopls​
    GO111MODULE=on go get
    Or, You can also use the vim-go plug-in
    Plug 'fatih/vim-go', { 'do': ':GoUpdateBinaries' }
    " run :GoInstallBinaries if setting up first time
    " this will also install the languager server for go (gopls) automatically
  3. 3.
    For bash, install bash-language-server​
    # if you have npm installed
    npm i -g bash-language-server
    # snap
    sudo snap install bash-language-server

Configure keybindings

The following boilerplate config can be used as it is
set completeopt=menuone,noselect
" Use <Tab> and <S-Tab> to navigate through popup menu
inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"
nnoremap <silent> gd <cmd>lua vim.lsp.buf.definition()<CR>
nnoremap <silent> gD <cmd>lua vim.lsp.buf.declaration()<CR>
nnoremap <silent> gr <cmd>lua vim.lsp.buf.references()<CR>
nnoremap <silent> gi <cmd>lua vim.lsp.buf.implementation()<CR>
nnoremap <silent> gh <cmd>lua vim.lsp.buf.hover()<CR>
nnoremap <silent> <C-k> <cmd>lua vim.lsp.buf.signature_help()<CR>
nnoremap <silent> <C-n> <cmd>lua vim.lsp.diagnostic.goto_prev()<CR>
nnoremap <silent> <C-p> <cmd>lua vim.lsp.diagnostic.goto_next()<CR>
" Auto format using LSP on save
autocmd BufWritePre *go,*.py lua vim.lsp.buf.formatting_sync(nil, 100)

Setup nvim-lspconfig

" Initialise server packs
lua <<EOF
# or require'lspconfig'.pyright.setup{}

Setup nvim-compe

let g:compe = {}
let g:compe.enabled = v:true
let g:compe.autocomplete = v:true
let g:compe.debug = v:false
let g:compe.min_length = 1
let g:compe.preselect = 'enable'
let g:compe.throttle_time = 80
let g:compe.source_timeout = 200
let g:compe.resolve_timeout = 800
let g:compe.incomplete_delay = 400
let g:compe.max_abbr_width = 100
let g:compe.max_kind_width = 100
let g:compe.max_menu_width = 100
let g:compe.documentation = v:true
let g:compe.source = {}
let g:compe.source.path = v:true
let g:compe.source.buffer = v:true
let g:compe.source.calc = v:true
let g:compe.source.nvim_lsp = v:true
let g:compe.source.nvim_lua = v:true
let g:compe.source.vsnip = v:true
let g:compe.source.ultisnips = v:true
let g:compe.source.luasnip = v:true
let g:compe.source.emoji = v:true
Notice: If you are embedding lua code in your vimscript config, use the following heredoc
lua <<EOF
-- [[ this is lua comment ]]
lua code
After setting up both the plugins open a file whose language server you installed and run :LspInfo to check server diagnostics

Spicy Stuff 🌶️

Below are some plugins which spice up the neovim lsp experience


Richer UI for LSP
Plug 'neovim/nvim-lspconfig'
Plug 'glepnir/lspsaga.nvim'
" lsp provider to find the cursor word definition and reference
nnoremap <silent> gh <cmd>lua require'lspsaga.provider'.lsp_finder()<CR>
" preview definition
nnoremap <silent> gd <cmd>lua require'lspsaga.provider'.preview_definition()<CR>
" show hover doc
nnoremap <silent> K <cmd>lua require('lspsaga.hover').render_hover_doc()<CR>
" scroll down hover doc or scroll in definition preview
nnoremap <silent> <C-f> <cmd>lua require('lspsaga.action').smart_scroll_with_saga(1)<CR>
" scroll up hover doc
nnoremap <silent> <C-b> <cmd>lua require('lspsaga.action').smart_scroll_with_saga(-1)<CR>
" code action
nnoremap <silent><leader>ca <cmd>lua require('lspsaga.codeaction').code_action()<CR>
vnoremap <silent><leader>ca :<C-U>lua require('lspsaga.codeaction').range_code_action()<CR>


Show function signature help as you type
Plug 'ray-x/lsp_signature.nvim'
lua <<EOF
require'lspconfig'.gopls.setup {
on_attach = function(client)
require 'lsp_signature'.on_attach(client)


Highlighting other uses of the current word under the cursor
Plug 'RRethy/vim-illuminate'
After installing make sure you have a language server running, it should work out of the box You can manually enable what files to use illuminate on as well
let g:Illuminate_ftwhitelist = ['vim', 'sh', 'python']