vim.lsp
Methods33
function M.rpc_response_error(code: integer, message: nil | string, data: any) -> lsp.ResponseError
Export these directly from rpc.
codeintegerRPC error code defined, see
vim.lsp.protocol.ErrorCodesmessagenil | stringarbitrary message to send to server
dataanyarbitrary data to send to server
@nodoc
function M._unsupported_method(method: vim.lsp.protocol.Method.ClientToServer) -> string
Called by the client when trying to call a method that's not supported in any of the servers registered for the current buffer.
methodvim.lsp.protocol.Method.ClientToServername of the method
- string
function M._get_workspace_folders(workspace_folders: string | lsp.WorkspaceFolder[] | nil) -> lsp.WorkspaceFolder[] | nil
function M._buf_get_line_ending(bufnr: integer) -> string
function M._buf_get_full_text(bufnr: integer) -> string
Returns full text of buffer {bufnr} as a string.
bufnrintegerBuffer handle, or 0 for current.
- string
Buffer text as string.
function M.config(name: string, cfg: vim.lsp.Config) -> nil
Sets the default configuration for an LSP client (or all clients if the special name "*" is used).
Can also be accessed by table-indexing (vim.lsp.config[…]) to get the resolved config, or redefine the config (instead of "merging" with the config chain).
Examples:
- Add root markers for ALL clients:
vim.lsp.config('*', {
root_markers = { '.git', '.hg' },
})
- Add capabilities to ALL clients:
vim.lsp.config('*', {
capabilities = {
textDocument = {
semanticTokens = {
multilineTokenSupport = true,
}
}
}
})
- Add root markers and capabilities for "clangd":
vim.lsp.config('clangd', {
root_markers = { '.clang-format', 'compile_commands.json' },
capabilities = {
textDocument = {
completion = {
completionItem = {
snippetSupport = true,
}
}
}
}
})
- (Re-)define the "clangd" configuration (overrides the resolved chain):
vim.lsp.config.clangd = {
cmd = {
'clangd',
'--clang-tidy',
'--background-index',
'--offset-encoding=utf-8',
},
root_markers = { '.clangd', 'compile_commands.json' },
filetypes = { 'c', 'cpp' },
}
- Get the resolved configuration for "emmylua_ls":
local cfg = vim.lsp.config.emmylua_ls
@since 13
function M.get_configs(filter: vim.lsp.get_configs.Filter | nil) -> vim.lsp.Config[]
Gets LSP configs.
See also [vim.lsp.getclients()] to get the runtime values of dynamic fields like `rootdir`, which depend on the current buffer/workspace/etc.
WARNING: May eagerly (prematurely!) evaluate config files in 'runtimepath'.
filtervim.lsp.get_configs.Filter | nil
- vim.lsp.Config[]
: List of |vim.lsp.Config| objects
@since 14
function M.enable(name: string | string[], enable: nil | boolean) -> nil
Enables a [lsp-config]: automatically attaches the client to any buffer based on the config filetypes, root_markers, and root_dir. See [lsp-activate] for details.
To disable, pass enable=false: Stops related clients and servers (force-stops servers after a timeout, unless exit_timeout=false).
Raises an error under the following conditions:
{name}is not a valid LSP config name (for example,'*').{name}corresponds to an LSP config file which raises an error.
If an error is raised when multiple names are provided, this function will have no side-effects; it will not enable/disable any configs, including ones which contain no errors.
Examples:
vim.lsp.enable('clangd')
vim.lsp.enable({'emmylua_ls', 'pyright'})
Example: To dynamically decide whether LSP is activated, define a |lsp-root_dir()| function which calls on_dir() only when you want that config to activate:
vim.lsp.config('emmylua_ls', {
root_dir = function(bufnr, on_dir)
if vim.fs.ext(vim.fn.bufname(bufnr)) ~= 'txt' then
on_dir(vim.fn.getcwd())
end
end
})
namestring | string[]Name(s) of client(s) to enable.
enablenil | booleanIf
true|nil, enables auto-activation of the given LSP config on current and future buffers. Iffalse, disables auto-activation and stops related LSP clients and servers (force-stops servers afterexit_timeoutmilliseconds).
- nil
@since 13
function M.is_enabled(name: string) -> boolean
Checks if the given LSP config is enabled (globally, not per-buffer).
Unlike vim.lsp.config['…'], this does not have the side-effect of resolving the config.
namestringConfig name
- boolean
function M.start(config: vim.lsp.ClientConfig, opts: vim.lsp.start.Opts | nil) -> client_id nil | integer
Create a new LSP client and start a language server or reuses an already running client if one is found matching name and root_dir. Attaches the current buffer to the client.
Example:
vim.lsp.start({
name = 'my-server-name',
cmd = {'name-of-language-server-executable'},
root_dir = vim.fs.root(0, {'pyproject.toml', 'setup.py'}),
})
See |vim.lsp.ClientConfig| for all available options. The most important are:
namearbitrary name for the LSP client. Should be unique per language server.cmdcommand string[] or function. See also |lsp-server|.root_dirpath to the project root. By default this is used to decide if an existing clientworkspace_folderslist of{ uri:string, name: string }tables specifying the project root
should be re-used. The example above uses |vim.fs.root()| to detect the root by traversing the file system upwards starting from the current directory until either a pyproject.toml or setup.py file is found.
folders used by the language server. If nil the property is derived from root_dir for convenience.
Language servers use this information to discover metadata like the dependencies of your project and they tend to index the contents within the project folder.
To ensure a language server is only started for languages it can handle, make sure to call |vim.lsp.start()| within a |FileType| autocmd. Either use |:au|, |nvimcreateautocmd()| or put the call in a ftplugin/<filetype_name>.lua (See |ftplugin-name|)
configvim.lsp.ClientConfigConfiguration for the server.
optsvim.lsp.start.Opts | nilOptional keyword arguments.
client_idnil | integer
@since 10
function M.status() -> string
Consumes the latest progress messages from all clients and formats them as a string. Empty if there are no clients or if no new messages
function M._set_defaults(client: vim.lsp.Client, bufnr: integer) -> nil
function M.start_client(config: vim.lsp.ClientConfig) -> (client_id nil | integer, nil | string)
Deprecated
configvim.lsp.ClientConfigConfiguration for the server.
client_idnil | integer|vim.lsp.getclientby_id()| Note: client may not be fully initialized. Use
on_initto do any actions once the client has been initialized.- nil | string
Error message, if any
function M.buf_attach_client(bufnr: integer, client_id: integer) -> success boolean
Implements the textDocument/did… notifications required to track a buffer for any language server.
Without calling this, the server won't be notified of changes to a buffer.
bufnrintegerBuffer handle, or 0 for current
client_idintegerClient id
successbooleantrueif client was attached successfully;falseotherwise
function M.buf_detach_client(bufnr: integer, client_id: integer) -> nil
Detaches client from the specified buffer. Note: While the server is notified that the text document (buffer) was closed, it is still able to send notifications should it ignore this notification.
bufnrintegerBuffer handle, or 0 for current
client_idintegerClient id
- nil
function M.buf_is_attached(bufnr: integer, client_id: integer) -> boolean
Checks if a buffer is attached for a particular client.
bufnrintegerBuffer handle, or 0 for current
client_idintegerthe client id
- boolean
function M.get_client_by_id(client_id: integer) -> client vim.lsp.Client | nil
Gets a client by id, or nil if the id is invalid or the client was stopped. The returned client may not yet be fully initialized.
client_idintegerclient id
clientvim.lsp.Client | nilrpc object
function M.get_buffers_by_client_id(client_id: integer) -> buffers integer[]
Deprecated
Returns list of buffers attached to client_id.
client_idintegerclient id
buffersinteger[]list of buffer ids
function M.stop_client(client_id: integer | integer[] | vim.lsp.Client[], force: nil | boolean | integer) -> nil
Deprecated
Stops a client(s).
You can also use the stop() function on a |vim.lsp.Client| object. To stop all clients:
vim.lsp.stop_client(vim.lsp.get_clients())
By default asks the server to shutdown, unless stop was requested already for this client (then force-stop is attempted, unless exit_timeout=false).
client_idinteger | integer[] | vim.lsp.Client[]id, list of id's, or list of |vim.lsp.Client| objects
forcenil | boolean | integerSee |Client:stop()|
- nil
function M.get_clients(filter: vim.lsp.get_clients.Filter | nil) -> vim.lsp.Client[]
Gets active clients.
filtervim.lsp.get_clients.Filter | nil
- vim.lsp.Client[]
: List of |vim.lsp.Client| objects
@since 12
function M.buf_request(bufnr: integer, method: vim.lsp.protocol.Method.ClientToServer.Request, params: table | fun(client: vim.lsp.Client, bufnr: integer) -> nil | table | nil, handler: lsp.Handler | nil, on_unsupported: fun() -> nil | nil) -> (client_request_ids {integer, integer}, _cancel_all_requests function)
bufnrintegerBuffer handle, or 0 for current.
methodvim.lsp.protocol.Method.ClientToServer.RequestLSP method name
paramstable | fun(client: vim.lsp.Client, bufnr: integer) -> nil | table | nilParameters to send to the server
handlerlsp.Handler | nilSee |lsp-handler| If nil, follows resolution strategy defined in |lsp-handler-configuration|
on_unsupportedfun() -> nil | nil
client_request_ids{integer, integer}Map of client-id:request-id pairs for all successful requests.
_cancel_all_requestsfunctionFunction which can be used to cancel all the requests. You could instead iterate all clients and call their
cancel_request()methods.
@nodoc
function M.buf_request_all(bufnr: integer, method: vim.lsp.protocol.Method.ClientToServer.Request, params: table | fun(client: vim.lsp.Client, bufnr: integer) -> nil | table | nil, handler: lsp.MultiHandler) -> cancel function
Sends an async request for all active clients attached to the buffer and executes the handler callback with the combined result.
bufnrintegerBuffer handle, or 0 for current.
methodvim.lsp.protocol.Method.ClientToServer.RequestLSP method name
paramstable | fun(client: vim.lsp.Client, bufnr: integer) -> nil | table | nilParameters to send to the server. Can also be passed as a function that returns the params table for cases where parameters are specific to the client.
handlerlsp.MultiHandler(function) Handler called after all requests are completed. Server results are passed as a
client_id:resultmap.
cancelfunctionFunction that cancels all requests.
@since 7
function M.buf_request_sync(bufnr: integer, method: vim.lsp.protocol.Method.ClientToServer.Request, params: table | fun(client: vim.lsp.Client, bufnr: integer) -> nil | table | nil, timeout_ms: nil | integer) -> (result {integer, { error: lsp.ResponseError?, result: any }} | nil, err nil | string)
Sends a request to all server and waits for the response of all of them.
Calls |vim.lsp.bufrequestall()| but blocks Nvim while awaiting the result. Parameters are the same as |vim.lsp.bufrequestall()| but the result is different. Waits a maximum of {timeout_ms}.
bufnrintegerBuffer handle, or 0 for current.
methodvim.lsp.protocol.Method.ClientToServer.RequestLSP method name
paramstable | fun(client: vim.lsp.Client, bufnr: integer) -> nil | table | nilParameters to send to the server. Can also be passed as a function that returns the params table for cases where parameters are specific to the client.
timeout_msnil | integerMaximum time in milliseconds to wait for a result. (default:
1000)
result{integer, { error: lsp.ResponseError?, result: any }} | nilMap of clientid:requestresult.
errnil | stringOn timeout, cancel, or error,
erris a string describing the failure reason, andresultis nil.
@since 7
function M.buf_notify(bufnr: nil | integer, method: vim.lsp.protocol.Method.ClientToServer.Notification, params: any) -> success boolean
Send a notification to a server
bufnrnil | integerThe number of the buffer
methodvim.lsp.protocol.Method.ClientToServer.NotificationName of the request method
paramsanyArguments to send to the server
successbooleantrue if any client returns true; false otherwise
@since 7
function M.omnifunc(findstart: integer, base: integer) -> Decided table | integer
Implements 'omnifunc' compatible LSP completion.
findstartinteger0 or 1, decides behavior
baseintegerfindstart=0, text to match against
Decidedtable | integerby {findstart}:
- findstart=1: column where the completion starts, or -2 or -3
- findstart=0: list of matches (actually just calls |complete()|)
|complete-functions| |complete-items| |CompleteDone|
function M.formatexpr(opts: vim.lsp.formatexpr.Opts | nil) -> 1 | 0
Provides an interface between the built-in client and a formatexpr function.
Currently only supports a single client. This can be set via vim.bo[bufnr].formatexpr = vim.lsp.formatexpr, or with a wrapper to pass options:
vim.bo[bufnr].formatexpr = function()
return vim.lsp.formatexpr({ timeout_ms = 250 })
end
function M.tagfunc(pattern: string, flags: string) -> tags table[]
Provides an interface between the built-in client and 'tagfunc'.
When used with normal mode commands (e.g. |CTRL-]|) this will invoke the "textDocument/definition" LSP method to find the tag under the cursor. Otherwise, uses "workspace/symbol". If no results are returned from any LSP servers, falls back to using built-in tags.
patternstringPattern used to find a workspace symbol
flagsstringSee |tag-function|
tagstable[]A list of matching tags
function M.foldexpr(lnum: integer) -> string
Provides an interface between the built-in client and a foldexpr function.
To use, set 'foldmethod' to "expr" and set the value of 'foldexpr':
vim.o.foldmethod = 'expr'
vim.o.foldexpr = vim.lsp.foldexpr
Or use it only when supported by checking for the "textDocument/foldingRange" capability in an |LspAttach| autocommand. Example:
vim.o.foldmethod = 'expr'
-- Default to treesitter folding
vim.o.foldexpr = vim.treesitter.foldexpr
-- Prefer LSP folding if client supports it
vim.api.nvim_create_autocmd('LspAttach', {
callback = function(ev)
local client = vim.lsp.get_client_by_id(ev.data.client_id)
if client:supports_method('textDocument/foldingRange') then
local win = vim.api.nvim_get_current_win()
vim.wo[win][0].foldexpr = vim.lsp.foldexpr
end
end,
})
lnumintegerline number
- string
function M.foldclose(kind: lsp.FoldingRangeKind, winid: nil | integer) -> nil
Close all {kind} of folds in the window with {winid}.
To automatically fold imports when opening a file, you can use an autocmd:
vim.api.nvim_create_autocmd('LspNotify', {
callback = function(ev)
if ev.data.method == 'textDocument/didOpen' then
vim.lsp.foldclose('imports', vim.fn.bufwinid(ev.buf))
end
end,
})
kindlsp.FoldingRangeKindKind to close, one of "comment", "imports" or "region".
winidnil | integerDefaults to the current window.
- nil
@since 13
function M.foldtext(lnum: nil | integer) -> string | (string, string[] | nil)[]
Provides a foldtext function that shows the collapsedText retrieved, defaults to the first folded line if collapsedText is not provided.
The displayed foldtext will be highlighted via treesitter.
lnumnil | integerline number (default: current fold start)
- string | (string, string[] | nil)[]
function M.client_is_stopped(client_id: integer) -> stopped boolean
Deprecated
client_idinteger
stoppedbooleantrue if client is stopped, false otherwise.
function M.set_log_level(level: string | integer) -> nil
Deprecated
Sets the global log level for LSP logging.
Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF"
Level numbers begin with "TRACE" at 0
Use lsp.log_levels for reverse lookup.
levelstring | integerthe case insensitive level name or number
- nil
|vim.lsp.log_levels|
function M.get_log_path() -> path string
Deprecated
Gets the path of the logfile used by the LSP client.
pathstringto log file
Fields26
M._capability : vim.lsp._capability
M._changetracking : vim.lsp._changetracking
M._folding_range : vim.lsp._folding_range
M._snippet_grammar : vim.lsp._snippet_grammar
M._tagfunc : vim.lsp._tagfunc
M._watchfiles : vim.lsp._watchfiles
M.buf : vim.lsp.buf
M.client : vim.lsp.client
M.codelens : vim.lsp.codelens
M.completion : vim.lsp.completion
M.diagnostic : vim.lsp.diagnostic
M.document_color : vim.lsp.document_color
M.handlers : vim.lsp.handlers
M.inlay_hint : vim.lsp.inlay_hint
M.inline_completion : vim.lsp.inline_completion
M.linked_editing_range : vim.lsp.linked_editing_range
M.log : vim.lsp.log
M.on_type_formatting : vim.lsp.on_type_formatting
M.protocol : vim.lsp.protocol
M.rpc : vim.lsp.rpc
M.semantic_tokens : vim.lsp.semantic_tokens
M.util : vim.lsp.util
M.client_errors: table
Error codes to be used with on_error from |vim.lsp.start_client|. Can be used to look up the string from a the number or the number from the string.
@nodoc
M._enabled_configs : {string, { resolved_config: vim.lsp.Config? }}
M.log_levels : {string, integer} | {integer, string}
Log level dictionary with reverse lookup as well.
Can be used to lookup the number from the name or the name from the number. Levels by name: "TRACE", "DEBUG", "INFO", "WARN", "ERROR", "OFF" Level numbers begin with "TRACE" at 0
@nodoc
M.commands : {string, fun(command: lsp.Command, ctx: table) -> nil}
Map of client-defined handlers implementing custom (off-spec) commands which a server may invoke. Each key is a unique command name; each value is a function which is called when an LSP action (code action, code lenses, …) requests it by name.
If an LSP response requests a command not defined client-side, Nvim will forward it to the server as workspace/executeCommand.
- Argument 1 is the
Command:
Command
title: String
command: String
arguments?: any[]
- Argument 2 is the |lsp-handler|
ctx.
Example:
vim.lsp.commands['java.action.generateToStringPrompt'] = function(_, ctx)
require("jdtls.async").run(function()
local _, result = request(ctx.bufnr, 'java/checkToStringStatus', ctx.params)
local fields = ui.pick_many(result.fields, 'Include item in toString?', function(x)
return string.format('%s: %s', x.name, x.type)
end)
local _, edit = request(ctx.bufnr, 'java/generateToString', { context = ctx.params; fields = fields; })
vim.lsp.util.apply_workspace_edit(edit, offset_encoding)
end)
end