Neovim plugin to auto install LSP servers
lazy-lsp.nvim
Neovim plugin to automatically install nvim-lspconfig language servers. It is an alternative to mason.nvim.
To ease the setup even further it can be complemented with lsp-zero.nvim.
Language servers are loaded in the background without a need of a manual user intervention. They are not installed upfront, but only on-demand after a source file for a given language is opened. The plugin works by relying on Nix package manager which works on Linux, macOS and Windows WSL.
Currently available 135 out of 386 servers in lspconfig, see the full list of supported servers.
Install
Requires Neovim v0.7.0+
- Install Nix package manager:
curl -L https://nixos.org/nix/install | sh - Install the plugin using lazy.nvim:
{
"dundalek/lazy-lsp.nvim",
dependencies = { "neovim/nvim-lspconfig" },
config = function()
require("lazy-lsp").setup {}
end
},
Alternatively, you can install the plugin via Nix/Home Manager.
- That's it, nothing else to install!
Setup
Quickest way to configure is to use lsp-zero.nvim which sets up key bindings and autocompletion.
{
"dundalek/lazy-lsp.nvim",
dependencies = {
"neovim/nvim-lspconfig",
{"VonHeikemen/lsp-zero.nvim", branch = "v3.x"},
"hrsh7th/cmp-nvim-lsp",
"hrsh7th/nvim-cmp",
},
config = function()
local lsp_zero = require("lsp-zero")
lspzero.onattach(function(client, bufnr) -- see :help lsp-zero-keybindings to learn the available actions lspzero.defaultkeymaps({ buffer = bufnr, preserve_mappings = false }) end)
require("lazy-lsp").setup {} end, },
Another approach is to configure manually by passing onattach handler which sets up keybindings and capabilities for autocompletion in the defaultconfig section.
Available configuration options:
require("lazy-lsp").setup {
-- By default all available servers are set up. Exclude unwanted or misbehaving servers.
excluded_servers = {
"ccls", "zk",
},
-- Alternatively specify preferred servers for a filetype (others will be ignored).
preferred_servers = {
markdown = {},
python = { "pyright" },
},
-- Default config passed to all servers to specify on_attach callback and other options.
default_config = {
flags = {
debouncetextchanges = 150,
},
-- onattach = onattach,
-- capabilities = capabilities,
},
-- Override config for specific servers that will passed down to lspconfig setup.
-- Note that the default_config will be merged with this specific configuration so you don't need to specify everything twice.
configs = {
lua_ls = {
settings = {
Lua = {
diagnostics = {
-- Get the language server to recognize the vim global
globals = { "vim" },
},
},
},
},
},
prefer_local = true, -- Prefer locally installed servers over nix-shell (default: true)
}
Experimental Neovim 0.11+ vim.lsp.config API support
Due to a change in config API warning message is shown when using the old lspconfig:
The require('lspconfig') "framework" is deprecated, use vim.lsp.config (see :help lspconfig-nvim-0.11) instead. Feature will be removed in nvim-lspconfig v3.0.0
You can opt into using these new APIs by setting usevimlsp_config = true:
require("lazy-lsp").setup {
usevimlsp_config = true, -- Requires Neovim 0.11+
}
Additionaly, instead of default_config and configs options you can use vim.lsp.config:
default_config = {...}becomesvim.lsp.config("*", {...})configs = {luals = {...}}becomesvim.lsp.config("luals", {...})
:checkhealth lazy-lsp.
Curated servers
The philosophy of this plugin is to enable all possible plugins by default to get the highest chance of LSP functionality being available, even at a cost of starting multiple servers for a single language. Any misbehaving or unwanted servers can be excluded one by one.
If this is not what you want, you can give a try to the curated configuration that enables smaller selection of recommended servers.
How it works
lazy-lsp registers all available configurations from lspconfig to start LSP servers by wrapping the commands in a nix shell or an older nix-shell environment. The nix shell prepares the environment by pulling all specified dependencies regardless of what is installed on the host system and avoids packages clashes. The first time a server is run there is a delay until dependencies are downloaded, but on subsequent runs the time to prepare the shell environment is negligible.
Versions
Nix uses channels to determine which packages and versions are available. I recommend using the unstable channel to get the latest versions.
If you encounter an older version of a language server try to run nix-channel --update to update channels. See docs about channels for more details how to work with channels.
Comparison with alternatives
- Installing manually, or via language specific package managers like npm, pip, etc. is a hassle.
- nvim-lsp-installer / mason.nvim
:LspInstall command needs to be run manually for each server
(vs. automatic installation in the background)
- Con: Additional dependencies like npm, pip, etc. need to be installed separately
(vs. a single Nix dependency)
- Con: Maintaining cross-platform installation scripts is a large maintanance burden
(vs. leveraging work by a large Nix community specializing in software packaging)
- lspcontainers.nvim - uses docker containers to run servers in a portable way which comes with an extra overhead
Development
The available lsp servers and stats are generated from nvim-lspconfig source.
Make a local copy:
mkdir tmp && cd tmp
git clone https://github.com/neovim/nvim-lspconfig.git
Run nix-shell to load dependencies needed for running the dev scripts.
Update servers.lua with new entries:
cd tmp/nvim-lspconfig
git pull
cd ../..
scripts/update.lua
Once done specifying servers, generate the stats in servers.md:
scripts/genstats.lua
Testing
Using Plenary for testing, see the Testing Guide for details.
Run tests (using Babashka task runner):
bb test:once
Run tests in watch mode:
bb test