mirror of
https://github.com/neovim/nvim-lspconfig
synced 2025-03-11 04:27:36 +00:00
Problem: :LspInfo has its own "inner platlform" of highlights, mappings etc. And it doesn't integrate with :checkhealth. Solution: - Move the lspinfo code to a healthcheck. - LspInfo features such as highlights, "floating window" presentation, etc., should be added to :checkhealth in Nvim core, if they are really needed. - Define a "q" mapping until Nvim stable has that in :checkhealth.
497 lines
20 KiB
Plaintext
497 lines
20 KiB
Plaintext
*lspconfig.txt* For Nvim version 0.8+
|
|
|
|
nvim-lspconfig provides user-contributed configs for the Nvim |lsp| client.
|
|
|
|
Type |gO| to see the table of contents.
|
|
|
|
==============================================================================
|
|
INTRODUCTION *lspconfig*
|
|
|
|
nvim-lspconfig is a collection of community-contributed configurations for the
|
|
Nvim LSP client. See |lspconfig-all| for the complete list of provided
|
|
configurations.
|
|
|
|
Note: nvim-lspconfig is just a convenience layer, it is NOT required for Nvim
|
|
|LSP| support. See |lsp-quickstart| to setup LSP without nvim-lspconfig.
|
|
|
|
==============================================================================
|
|
QUICKSTART *lspconfig-quickstart*
|
|
|
|
1. Install a language server, e.g. pyright. >
|
|
npm i -g pyright
|
|
2. Add the language server setup to your init.lua. >
|
|
require'lspconfig'.pyright.setup{}
|
|
3. Ensure your project/workspace contains a root marker which matches the
|
|
server requirements specified in |lspconfig-all|.
|
|
4. Open a code file in Nvim. LSP will attach and provide diagnostics. >
|
|
nvim main.py
|
|
5. Run `:checkhealth lsp` to see the status or to troubleshoot.
|
|
|
|
==============================================================================
|
|
USAGE *lspconfig-usage*
|
|
|
|
`lspconfig` consists of a collection of language server configurations. Each
|
|
configuration exposes a `setup{}` metamethod which makes it easy to directly
|
|
use the default configuration or selectively override the defaults. `setup{}`
|
|
is the primary interface by which users interact with `lspconfig`.
|
|
|
|
To activate a config, call its `setup{}` function. Each config name listed in
|
|
|lspconfig-all| is available as `config.<name>`. For example to activate the
|
|
"clangd" config: >lua
|
|
|
|
require'lspconfig'.clangd.setup{}
|
|
<
|
|
*lspconfig-config_def*
|
|
You can use the `config_def` field to get the static config definition without
|
|
activating it: >lua
|
|
|
|
local config = require'lspconfig'.clangd.config_def
|
|
<
|
|
*lspconfig-setup*
|
|
`setup{}` wraps |vim.lsp.start_client()| or |vim.lsp.buf_attach_client()|
|
|
functions (depending on whether the current file belongs to a project with
|
|
a currently running client; see |lspconfig-root-detection|).
|
|
|
|
`setup{}` takes a superset of the keys listed in |vim.lsp.start_client()| with
|
|
the following added keys:
|
|
|
|
- {root_dir} (`function(filename, bufnr)`) Returns either a filepath (string)
|
|
or nil. The language server will only start if the function returns
|
|
a filepath.
|
|
|
|
If a root directory (string) is returned which is unique from any previously
|
|
returned root_dir, a new server will be spawned with that root directory.
|
|
See |lspconfig-root-detection| for more details
|
|
|
|
- {name} (`string`) Defaults to the server's name (`clangd`, `pyright`, etc.).
|
|
|
|
- {filetypes} (`list[string] | nil`) Set of filetypes for which to attempt to
|
|
resolve {root_dir}. May be empty, or server may specify a default value.
|
|
|
|
- {autostart} (`bool`) (default: true) Controls if the `FileType` autocommand
|
|
that launches a language server is created. If `false`, allows for deferring
|
|
language servers until manually launched with `:LspStart`.
|
|
|
|
- {single_file_support} (`bool`) (default: nil) Determines if a server is
|
|
started without a matching root directory. See |lspconfig-single-file-support|.
|
|
|
|
- {on_new_config} (`function(new_config, new_root_dir)`) Function executed
|
|
after a root directory is detected. This is used to modify the server
|
|
configuration (including `cmd` itself). Most commonly, this is used to
|
|
inject additional arguments into `cmd`.
|
|
|
|
If overriding `on_new_config`, ensure that you read the `on_new_config`
|
|
defined in the source file of the default configuration in `lspconfig`. The
|
|
original `on_new_config` snippet for a given server should likely be
|
|
included in your new override. Some configurations use `on_new_config` to
|
|
dynamically set or modify `cmd`.
|
|
|
|
Note: all fields passed to `setup{}` override the respective field in the
|
|
default configuration. There is no composition.
|
|
|
|
All `config` elements described in `:help vim.lsp.start_client()` can
|
|
additionally be overridden via the `setup{}` call. The most commonly passed
|
|
overrides to `setup{}` are:
|
|
|
|
- {settings} `table <string, string|table|bool>`
|
|
|
|
The `settings` table is sent after initialization via a
|
|
`workspace/didChangeConfiguration` notification from the Nvim client to
|
|
the language server. These settings allow a user to change optional runtime
|
|
settings of the language server.
|
|
|
|
As an example, to set the following settings found in the pyright
|
|
documentation:
|
|
|
|
`pyright.disableLanguageServices`: `boolean`
|
|
`pyright.disableOrganizeImports`: `boolean`
|
|
|
|
Nested keys need to be translated into a nested table and passed to
|
|
the settings field in `setup{}` as follows: >lua
|
|
require('lspconfig').pyright.setup{
|
|
settings = {
|
|
pyright = {
|
|
disableLanguageServices = true,
|
|
disableOrganizeImports = true,
|
|
}
|
|
}
|
|
}
|
|
<
|
|
==============================================================================
|
|
OVERRIDING GLOBAL DEFAULTS *lspconfig-global-defaults*
|
|
|
|
The global defaults for all servers can be overridden by extending the
|
|
`default_config` table. `setup{}` can override these defaults. >lua
|
|
|
|
local lspconfig = require'lspconfig'
|
|
lspconfig.util.default_config = vim.tbl_extend(
|
|
"force",
|
|
lspconfig.util.default_config,
|
|
{
|
|
autostart = false,
|
|
handlers = {
|
|
["window/logMessage"] = function(err, method, params, client_id)
|
|
if params and params.type <= vim.lsp.protocol.MessageType.Log then
|
|
vim.lsp.handlers["window/logMessage"](err, method, params, client_id)
|
|
end
|
|
end,
|
|
["window/showMessage"] = function(err, method, params, client_id)
|
|
if params and params.type <= vim.lsp.protocol.MessageType.Warning.Error then
|
|
vim.lsp.handlers["window/showMessage"](err, method, params, client_id)
|
|
end
|
|
end,
|
|
}
|
|
}
|
|
)
|
|
<
|
|
|
|
==============================================================================
|
|
SETUP HOOK *lspconfig-setup-hook*
|
|
|
|
`lspconfig` will execute the `on_setup` hook for each setup call to a server after
|
|
validating its configuration, and before attempting to launch the server
|
|
itself. One typical usage is to allow ad-hoc substitution for any
|
|
configuration entry, such as `cmd`.
|
|
|
|
>
|
|
local lspconfig = require 'lspconfig'
|
|
lspconfig.util.on_setup = lspconfig.util.add_hook_before(lspconfig.util.on_setup, function(config)
|
|
if some_condition and config.name == "clangd" then
|
|
local custom_server_prefix = "/my/custom/server/prefix"
|
|
config.cmd = { custom_server_prefix .. "/bin/clangd" }
|
|
end
|
|
end)
|
|
|
|
|
|
Note: This is primarily targeted at plugins developers, so make sure to use
|
|
`util.add_hook_before()` as a wrapper instead of overriding the original function
|
|
completely, to void breaking external integrations with lspconfig.
|
|
|
|
==============================================================================
|
|
SERVER CONFIGS *lspconfig-configurations*
|
|
|
|
See |lspconfig-all| for the list of provided LSP configurations.
|
|
|
|
For servers for which there is not a configuration, it is necessary to define
|
|
a configuration. This can be done through the `configs` module.
|
|
|
|
The `configs` module is a singleton where configs are defined. The
|
|
`vim.validate` schema is: >
|
|
|
|
configs.SERVER_NAME = {
|
|
default_config = {'t'},
|
|
on_new_config = {'f', true},
|
|
on_attach = {'f', true},
|
|
commands = {'t', true},
|
|
docs = {'t', true},
|
|
}
|
|
<
|
|
where the structure of `docs` is: >
|
|
|
|
docs = {
|
|
description = {'s', true},
|
|
default_config = {'t', true},
|
|
}
|
|
<
|
|
`commands` is a map of `name:definition` key:value pairs, where `definition`
|
|
is a list whose first value is a function implementing the command, and the
|
|
rest are either array values which will be formed into flags for the command,
|
|
or special keys like `description`.
|
|
|
|
WARNING: Commands is deprecated and will be removed in future releases.
|
|
It is recommended to use `vim.api.nvim_create_user_command()` instead in an
|
|
|LspAttach| autocommand handler.
|
|
|
|
Example:
|
|
>
|
|
local function organize_imports()
|
|
local params = {
|
|
command = 'pyright.organizeimports',
|
|
arguments = { vim.uri_from_bufnr(0) },
|
|
}
|
|
vim.lsp.buf.execute_command(params)
|
|
end
|
|
|
|
vim.api.nvim_create_autocmd('LspAttach', {
|
|
callback = function(ev)
|
|
local client = vim.lsp.get_client_by_id(ev.data.client_id)
|
|
if client.name == "pyright" then
|
|
vim.api.nvim_create_user_command("PyrightOrganizeImports", organize_imports, {desc = 'Organize Imports'})
|
|
end
|
|
end
|
|
end
|
|
|
|
require("lspconfig")['pyright'].setup{}
|
|
<
|
|
|
|
The `configs.__newindex` metamethod consumes the config definition and returns
|
|
an object with a `setup()` method, to be invoked by users:
|
|
>
|
|
require'lspconfig'.SERVER_NAME.setup{}
|
|
|
|
After you set `configs.SERVER_NAME` you can add arbitrary language-specific
|
|
functions to it if necessary.
|
|
|
|
Example:
|
|
>
|
|
configs.texlab.buf_build = buf_build
|
|
<
|
|
|
|
==============================================================================
|
|
ADDING NEW SERVERS *lspconfig-new*
|
|
|
|
The steps for adding and enabling a new server configuration are:
|
|
|
|
1. Define the configuration (see also |vim.fs.root()|): >lua
|
|
local lspconfig = require 'lspconfig'
|
|
local configs = require 'lspconfig.configs'
|
|
|
|
-- Check if the config is already defined (useful when reloading this file)
|
|
if not configs.foo_lsp then
|
|
configs.foo_lsp = {
|
|
default_config = {
|
|
cmd = {'/home/neovim/lua-language-server/run.sh'},
|
|
filetypes = {'lua'},
|
|
root_dir = function(fname)
|
|
return lspconfig.util.find_git_ancestor(fname)
|
|
end,
|
|
settings = {},
|
|
},
|
|
}
|
|
end
|
|
|
|
2. Call `setup()` to enable the FileType autocmd >
|
|
lspconfig.foo_lsp.setup{}
|
|
<
|
|
==============================================================================
|
|
ROOT DETECTION *lspconfig-root-detection*
|
|
*lspconfig-root-dir*
|
|
|
|
WARNING: This API is deprecated. Use |vim.fs.root()| from Nvim core instead.
|
|
|
|
A project's `root_dir` is used by `lspconfig` to determine whether `lspconfig`
|
|
should start a new server, or attach a previous one, to the current file.
|
|
|
|
`lspconfig` automatically launches language servers by defining a filetype
|
|
autocommand based on the `filetypes` specified in the default configuration of
|
|
each server, optionally overridable by the `filetypes` table passed to
|
|
`setup`.
|
|
|
|
This autocommand triggers a search from the current file position in the
|
|
filesystem hierarchy up to the top level directory of your filesystem. The
|
|
`root_dir` field of each configuration is a function that returns true if the
|
|
current directory in this traversal matches a given root pattern.
|
|
|
|
The following utility functions are provided by `lspconfig`. Each function call
|
|
below returns a function that takes as its argument the current buffer path.
|
|
|
|
- `util.root_pattern`: function which takes multiple arguments, each
|
|
corresponding to a different root pattern against which the contents of the
|
|
current directory are matched using |vim.fn.glob()| while traversing up the
|
|
filesystem. Parent directories are traversed once per pattern, in the order
|
|
the patterns are specified. >
|
|
root_dir = util.root_pattern('pyproject.toml', 'requirements.txt')
|
|
- `util.find_git_ancestor`: a function that locates the first parent directory
|
|
containing a `.git` directory. >
|
|
root_dir = util.find_git_ancestor
|
|
- `util.find_node_modules_ancestor`: a function that locates the first parent
|
|
directory containing a `node_modules` directory. >
|
|
root_dir = util.find_node_modules_ancestor
|
|
- `util.find_package_json_ancestor`: a function that locates the first parent
|
|
directory containing a `package.json`. >
|
|
root_dir = util.find_package_json_ancestor
|
|
<
|
|
Note: On Windows, `lspconfig` always assumes forward slash normalized paths with
|
|
capitalized drive letters.
|
|
|
|
==============================================================================
|
|
ADVANCED ROOT DIRECTORY DETECTION *lspconfig-root-advanced*
|
|
*lspconfig-root-composition*
|
|
|
|
WARNING: This API is deprecated. Use |vim.fs.root()| from Nvim core instead.
|
|
|
|
The `root_dir` key in `config` and `setup` can hold any function of the form
|
|
>
|
|
function custom_root_dir(filename, bufnr)
|
|
returns nil | string
|
|
>
|
|
This allows for rich composition of root directory patterns which is necessary
|
|
for some project structures. Example (for Kotlin): >lua
|
|
|
|
local root_files = {
|
|
'settings.gradle', -- Gradle (multi-project)
|
|
'settings.gradle.kts', -- Gradle (multi-project)
|
|
'build.xml', -- Ant
|
|
'pom.xml', -- Maven
|
|
}
|
|
|
|
local fallback_root_files = {
|
|
'build.gradle', -- Gradle
|
|
'build.gradle.kts', -- Gradle
|
|
}
|
|
root_dir = function(fname)
|
|
local primary = util.root_pattern(unpack(root_files))(fname)
|
|
local fallback = util.root_pattern(unpack(fallback_root_files))(fname)
|
|
return primary or fallback
|
|
end
|
|
<
|
|
Browsing the source of the default configurations is recommended.
|
|
|
|
==============================================================================
|
|
SINGLE FILE SUPPORT *lspconfig-single-file-support*
|
|
|
|
Language servers require each project to have a `root` in order to provide
|
|
features that require cross-file indexing.
|
|
|
|
Some servers support not passing a root directory as a proxy for single file
|
|
mode under which cross-file features may be degraded.
|
|
|
|
`lspconfig` offers limited support for an implicit single-file mode by:
|
|
|
|
- first trying to resolve the root directory pattern
|
|
- then, if `single_file_support` is enabled for a given language server
|
|
configuration, starting the server without sending `rootDirectory` or
|
|
`workspaceFolders` during initialization.
|
|
- attaching subsequent files in the parent directory to the same server
|
|
instance, depending on filetype.
|
|
- also supports unnamed buffer if filetype matches the server filetype
|
|
settings.
|
|
|
|
Cross-file features (navigation, hover) may or may not work depending on the
|
|
language server. For a full feature-set, consider moving your files to a
|
|
directory with a project structure `lspconfig` can infer.
|
|
|
|
Note that in the event that the LSP specification is extended to support a
|
|
standard for single-file mode, lspconfig will adopt that standard.
|
|
|
|
==============================================================================
|
|
COMMANDS *lspconfig-commands*
|
|
|
|
:LspInfo *:LspInfo*
|
|
Deprecated alias to `:check lspconfig`.
|
|
Shows the status of all configured language servers. Note that client id
|
|
refers to the Nvim RPC channel connected to a given language server. Also
|
|
lists deprecated servers.
|
|
|
|
The following commands support tab-completion for all arguments. All commands
|
|
that require a client id can either leverage tab-completion or the info
|
|
contained in `:LspInfo`:
|
|
|
|
:LspStart [config_name] *:LspStart*
|
|
Launches the requested (configured) client, but only if it successfully
|
|
resolves a root directory. Note: Defaults to all configured servers matching
|
|
the current buffer filetype.
|
|
|
|
:LspStop [client_id] *:LspStop*
|
|
Stops the server with the given client id. Defaults to stopping all servers
|
|
active on the current buffer. To force stop a language server: >
|
|
:LspStop <client_id> ++force
|
|
|
|
:LspRestart [client_id] *:LspRestart*
|
|
Restarts the client with the given client id, and attempts to reattach to all
|
|
previously attached buffers.
|
|
|
|
==============================================================================
|
|
COMPLETION SUPPORT *lspconfig-completion*
|
|
|
|
See |lsp-config|.
|
|
|
|
==============================================================================
|
|
DEBUGGING AND TROUBLESHOOTING *lspconfig-debugging*
|
|
|
|
While using language servers should be easy, debugging issues can be
|
|
challenging. First, it is important to identify the source of the issue, which
|
|
is typically (in rough order):
|
|
|
|
- the language server itself
|
|
- a plugin
|
|
- overrides in a user configuration
|
|
- the built-in client in Nvim core
|
|
- nvim-lspconfig
|
|
|
|
The first step in debugging is to test with a minimal configuration:
|
|
https://github.com/neovim/neovim/issues/new?assignees=&labels=bug%2Clsp&template=lsp_bug_report.yml(such as
|
|
Historically, many problems are due to plugins or misconfiguration.
|
|
|
|
Should that fail, identifying which component is the culprit is challenging.
|
|
The following are the only categories of bugs that pertain to nvim-lspconfig.
|
|
|
|
- The root directory inferred for your project is wrong, or it should be
|
|
detected but is not due to a bug in the nvim-lspconfig path utilities.
|
|
- The server is launching, but you believe that the default settings,
|
|
initialization options, or command arguments are suboptimal and should be
|
|
replaced based on your understanding of the server documentation.
|
|
|
|
All bugs Nvim's built-in client should be reported to the Nvim core issue
|
|
tracker. All bugs pertaining to plugins should be reported to the respective
|
|
plugin. All missing features in a language server should be reported to the
|
|
upstream language server issue tracker.
|
|
|
|
For debugging nvim-lspconfig issues, the most common hurdles users face are:
|
|
|
|
- The language server is not installed or is otherwise not executable.
|
|
nvim-lspconfig does not install language servers for you. Ensure the `cmd`
|
|
defined in |lspconfig-all| is executable from the command line. If the
|
|
absolute path to the binary is not supplied in `cmd`, ensure it is on your
|
|
PATH.
|
|
- Missing filetype plugins. Certain languages are not detecting by
|
|
Vim/Nvim because they have not yet been added to the filetype detection
|
|
system. Ensure `:set ft?` shows the filetype and not an empty value.
|
|
- Not triggering root detection. nvim-lspconfig is built around the concept of projects. See
|
|
|lspconfig-root-detection| for more details. Most of the time,
|
|
initializing a git repo will suffice.
|
|
- Not triggering root detection. Some language servers will only start
|
|
if it is opened in a directory, or child directory, containing a file
|
|
which signals the *root* of the project. Most of the time, this is
|
|
a `.git` folder, but each server defines the root config in the lua file.
|
|
See |lspconfig-all| or the source code for the list of root directories.
|
|
- Misconfiguration. Often users will override `cmd`, `on_init`, or
|
|
`handlers`. Ensure that you debug by using a stock configuration to ensure
|
|
your customizations are not introducing issues.
|
|
|
|
|LspInfo| provides an overview of your active and configured language servers
|
|
which can be useful for debugging.
|
|
|
|
Note that it will not report any configuration changes applied in
|
|
`on_new_config`.
|
|
|
|
==============================================================================
|
|
LOGGING *lspconfig-logging*
|
|
|
|
When debugging language servers, it is helpful to enable additional logging in
|
|
the built-in client, specifically considering the RPC logs. Example: >lua
|
|
|
|
vim.lsp.set_log_level 'trace'
|
|
if vim.fn.has 'nvim-0.5.1' == 1 then
|
|
require('vim.lsp.log').set_format_func(vim.inspect)
|
|
end
|
|
<
|
|
Attempt to run the language server, and open the log with:
|
|
|
|
>
|
|
:LspLog
|
|
<
|
|
Note that `ERROR` messages containing `stderr` only indicate that the log was
|
|
sent to `stderr`. Many servers counter-intuitively send harmless messages
|
|
via stderr.
|
|
|
|
==============================================================================
|
|
SCOPE *lspconfig-scope*
|
|
|
|
`lspconfig` is a community effort to create default configurations that fit
|
|
within the scope of an official plugin for Nvim. All features that are not
|
|
strictly providing default configurations for language servers will be removed
|
|
from `lspconfig` in time.
|
|
|
|
==============================================================================
|
|
Highlights *lspconfig-highlight*
|
|
|
|
WARNING: The `require('lspconfig.ui.windows')` API was removed.
|
|
LspInfo is provided by a healthcheck instead: >
|
|
:checkhealth lspconfig
|
|
<
|
|
|
|
==============================================================================
|
|
|
|
vim:tw=78:ts=8:ft=help:norl:
|