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.
Install language server pack for python (make sure you are running latest pip and Python 3.6+)
bashpip install 'python-language-server[all]'
Another alternative to python-language-server is pyright
bashpip3 install pyright
Language server pack for go is maintained by the go team itself. Use
go get
to install goplsbashGO111MODULE=on go get golang.org/x/tools/gopls@latest
Or, You can also use the
vim-go
plug-invimPlug 'fatih/vim-go', { 'do': ':GoUpdateBinaries' } " run :GoInstallBinaries if setting up first time " this will also install the languager server for go (gopls) automatically
For bash, install bash-language-server
bash# if you have npm installed npm i -g bash-language-server # snap sudo snap install bash-language-server
- To install other language servers visit langserver.org and choose accordingly.
- After that check the necessary config for neovim setup
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
lspsaga.nvim
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>
lsp_signature
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
vim-illuminate
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']