Easier way to setup LSP on neovim
September 10, 2021 — (Last edited on November 09, 2021)
Problem
You probably might already be used to the standard way to setup LSP on neovim
with lspconfig
, but on the long run, depending on the number of different
languages you’re working with, you might stumble upon the following problem
(quoted from this article)
For example, you install
pyright
withnpm
,gopls
withgo get
,cmake-language-server
withpip
,rust_analyzer
by downloading a release from GitHub, andyaml-language-server
can only be installed withyarn
but not withnpm
. And it gets worse! To get an up to date version of the HTML/CSS/JSON language servers you need to download the latest VSCode release and extract the language servers from there. Similarly, to get thetailwindcss-intellisense
language server, you’ve got to extract it from the VSCode extension.
You get the point, having such a spaghetti of package managers that you probably won’t use more than once is not desirable (and we’re not even including the part of migrating all this mess to a new system) is not desirable
Solution
The answer for such problem is nvim-lsp-installer
,
in short, it provides a nice :LspInstall <language>
for leveraging all the
setup required for getting a LSP working
Installation
You can install it with your neovim plugin manager of choice, i’ll be using paq-nvim
as an example:
require 'paq-nvim' {
-- considering that you already have it at this point
'neovim/nvim-lspconfig',
'williamboman/nvim-lsp-installer'
}
Setup
First, the basics, import nvim-lsp-installer
, enable snippet support with
a completion engine of your choice (i’ll be using nvim-cmp
), and create a
table containing language servers names as keys, and their respective
configuration (if needed) as values
local lsp_installer = require 'nvim-lsp-installer'
-- enabling snippetSupport is required in order to make LSP work
local capabilities = vim.lsp.protocol.make_client_capabilities()
capabilities.textDocument.completion.completionItem.snippetSupport = true
capabilities = require 'cmp_nvim_lsp'.update_capabilities(capabilities)
local language_servers = {
['css'] = {},
['html'] = {},
['json'] = {},
['typescript'] = {}
}
Now, we must loop the language_servers
table in order to properly install
each one of the specified language servers, and set them up with their
respective configurations
-- installs language servers
local installed_servers = require 'nvim-lsp-installer.servers'
for server_name in pairs(language_servers) do
local ok, server = installed_servers.get_server(server_name)
if ok and not server:is_installed() then
server:install()
end
end
Having done that, now the last step is starting up installed server, this can
be done with the on_server_ready
listener:
lsp_installer.on_server_ready(function(server)
local opts = language_servers[server.name]
server:setup(opts)
end)
Shoutout to Karim Abou Zeid for creating such an amazing plugin!