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'

Or

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. 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. Language server pack for go is maintained by the go team itself. Use go get to install gopls

    GO111MODULE=on go get golang.org/x/tools/gopls@latest

    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. 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
require'lspconfig'.gopls.setup{}
require'lspconfig'.pyls.setup{}
# or require'lspconfig'.pyright.setup{}
require'lspconfig'.bashls.setup{}
EOF

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
   ...
EOF

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)
end,
}
EOF

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']

Resources

Last updated