- Neovim 0.6 or later
- Lint task requires luacheck and stylua. If using nix, you can use
nix develop
to install these to a local nix shell. - Documentation is generated by
scripts/docgen.lua
.- Only works on linux and macOS
The point of lspconfig is to provide the minimal configuration necessary for a server to act in compliance with the language server protocol. In general, if a server requires custom client-side commands or off-spec handlers, then the server configuration should be added without those in lspconfig and receive a dedicated plugin such as nvim-jdtls, nvim-metals, etc.
- To avoid duplicate work, create a draft pull request.
- Avoid cosmetic changes to unrelated files in the same commit.
- Use a feature branch instead of the master branch.
- Use a rebase workflow for small PRs.
- After addressing review comments, it's fine to rebase and force-push.
The general form of adding a new language server is to start with a minimal skeleton. This includes populated the config
table with a default_config
and docs
table.
When choosing a server name, convert all dashes (-
) to underscores (_
) If the name of the server is a unique name (pyright
, clangd
) or a commonly used abbreviation (zls
), prefer this as the server name. If the server instead follows the pattern x-language-server, prefer the convention x_ls
(jsonnet_ls
).
default_config
should include, at minimum the following:
cmd
: a list which includes the executable name as the first entry, with arguments constituting subsequent list elements (--stdio
is common). Note that Windows has a limitation when it comes to directly invoking a server that's installed bynpm
orgem
, so it requires additional handling.
local bin_name = 'typescript-language-server'
local cmd = { bin_name, '--stdio' }
if vim.fn.has 'win32' == 1 then
cmd = { 'cmd.exe', '/C', bin_name, '--stdio' }
end
filetypes
: a list for filetypes aroot_dir
: a function (or function handle) which returns the root of the project used to determine if lspconfig should launch a new language server, or attach a previously launched server when you open a new buffer matching the filetype of the server. Note, lspconfig does not offer a dedicated single file mode (this is not codified in the spec). Do not addvim.fn.cwd
orutil.path.dirname
inroot_dir
. A future version of lspconfig will provide emulation of a single file mode until this is formally codified in the specification. A good fallback isutil.find_git_ancestor
, see other configurations for examples.
Additionally, the following options are often added:
init_options
: a table sent during initialization, corresponding to initializationOptions sent in initializeParams as part of the first request sent from client to server during startup.settings
: a table sent duringworkspace/didChangeConfiguration
shortly after server initialization. This is an undocumented convention for most language servers. There is often some duplication with initOptions.
An example for adding a new language server is shown below for pyright
, a python language server included in lspconfig:
local util = require 'lspconfig.util'
local bin_name = 'pyright-langserver'
local cmd = { bin_name, '--stdio' }
if vim.fn.has 'win32' == 1 then
cmd = { 'cmd.exe', '/C', bin_name, '--stdio' }
end
local root_files = {
'pyproject.toml',
'setup.py',
'setup.cfg',
'requirements.txt',
'Pipfile',
'pyrightconfig.json',
}
local function organize_imports()
local params = {
command = 'pyright.organizeimports',
arguments = { vim.uri_from_bufnr(0) },
}
vim.lsp.buf.execute_command(params)
end
return {
default_config = {
cmd = cmd,
filetypes = { 'python' },
root_dir = util.root_pattern(unpack(root_files)),
single_file_support = true,
settings = {
python = {
analysis = {
autoSearchPaths = true,
useLibraryCodeForTypes = true,
diagnosticMode = 'workspace',
},
},
},
},
commands = {
PyrightOrganizeImports = {
organize_imports,
description = 'Organize Imports',
},
},
docs = {
description = [[
https://github.com/microsoft/pyright
`pyright`, a static type checker and language server for python
]],
},
}
lspconfig, like neovim core, follows the conventional commit style please submit your commits accordingly. Generally commits will be of the form:
feat: add lua-language-server support
fix(lua-language-server): update root directory pattern
docs: update README.md
with the commit body containing additional details.
PRs are checked with luacheck, StyLua and selene. Please run the linter locally before submitting a PR:
make lint
Github Actions automatically generates server_configurations.md
. Only modify scripts/README_template.md
or the docs
table in the server config (the lua file). Do not modify server_configurations.md
directly.
To preview the generated server_configurations.md
locally, run scripts/docgen.lua
from
nvim
(from the project root):
nvim -R -Es +'set rtp+=$PWD' +'luafile scripts/docgen.lua'