Previously, the handler signature was:
function(err, method, params, client_id, bufnr, config)
In order to better support external plugins that wish to extend the
protocol, there is other information which would be advantageous to
forward to the client, such as the original params of the request that
generated the callback.
In order to do this, we would need to break symmetry of the handlers, to
add an additional "params" as the 7th argument.
Instead, this PR changes the signature of the handlers to:
function(err, result, ctx, config)
where ctx (the context) includes params, client_id, and bufnr. This also leaves
flexibility for future use-cases.
BREAKING_CHANGE: changes the signature of the built-in client handlers, requiring
updating handler calls
Resolve an issue with deferred clearing of highlight failing if the
buffer is deleted before the timeout by checking whether the
buffer is valid first.
Declaration, type-definition, and implementation capabilities were
previously disabled if the client received table output from the server
capabilities. The workDoneProgress capability is sent for many servers
for all supported capabilities as part of this table. Default to setting
capability to table instead of false.
The official developer documentation in in :h dev-lua-doc specifies to
use "--@" for special/magic tokens. However, this format is not
consistent with EmmyLua notation (used by some Lua language servers) nor
with the C version of the magic docstring tokens which use three comment
characters.
Further, the code base is currently split between usage of "--@",
"---@", and "--- @". In an effort to remain consistent, change all Lua
magic tokens to use "---@" and update the developer documentation
accordingly.
According to the protocol definition `rootPath`, `rootUri` and
`workspaceFolders` are allowed to be null.
Some language servers utilize this to provide "single file" support.
If all three are null, they don't attempt to index a directory but
instead only provide capabilities for a single file.
This changes the behavior of the hl_cache to the old one.
- when the capture exists as a hlgroup -> use it
- when hl_map contains a mapping -> use it
- else do nothing (before: map capture to non-existing capture)
Before also captures `@foo.bar` would intend to use the hlgroup `foo.bar`
which results in a confusing error since hlgroups can't contain dots.
Add a new function to redraw diagnostics from the current diagnostic
cache, without receiving a "publishDiagnostics" message from the server.
This is already being done in two places in the Lua stdlib, so this
function unifies that functionality in addition to providing it to third
party plugins.
An example use case for this could be a command or key-binding for
toggling diagnostics virtual text. The virtual text configuration option
can be toggled using `vim.lsp.with` followed by
`vim.lsp.diagnostic.redraw()` to immediately redraw the diagnostics
with the updated setting.
The handlers for textDocument/references, textDocument/documentSymbol,
and workspace/symbol open their results in the quickfix list by default
and are not configurable. They are also incompatible with `vim.lsp.with`
as they do not accept a configuration parameter.
Add a `config` parameter to the handler for these three messages which
allows them to be configured with `vim.lsp.with`. Additionally, add a
new configuration option 'loclist' that, when true, causes these
handlers to open their results in the location list rather than the
quickfix list.
Some language servers *cough*rust-analyzer*cough* need an empty/custom
workspaceFolders for certain usecases. For example, rust-analyzer
needs an empty workspaceFolders table for standalone file support
(See https://github.com/rust-analyzer/rust-analyzer/pull/8955).
This can also be useful for other languages that need to commonly
open a certain directory (like flutter or lua), which would help
prevent spinning up a new language server altogether.
In case no workspaceFolders are passed, we fallback to what we had
before.
Passing `nil` is equivalent to passing 0, i.e. it simply uses the
current buffer number.
This fixes a bug when vim.lsp.diagnostic.disable() is called without
arguments.
Add two new methods to allow diagnostics to be disabled (and re-enabled)
in the current buffer. When diagnostics are disabled they are simply not
displayed to the user, but they are still sent by the server and
processed by the client.
Disabling diagnostics can be helpful in a number of scenarios. For
example, if one is working on a buffer with an overwhelming amount of
diagnostic warnings it can be helpful to simply disable diagnostics
without disabling the LSP client entirely. This also allows users more
flexibility on when and how they may want diagnostic information to be
displayed. For example, some users may not want to display diagnostic
information until after the buffer is first written.
An empty table was previously always treated as a list, which means that
while merging tables, whenever an empty table was encountered it would
always truncate any table on the left.
`vim.tbl_deep_extend("force", { b = { a = 1 } }, { b = {} })`
Before: `{ b = {} }`
After: `{ b = { a = 1 } }`
the `textDocument/rangeFormatting` nad `textDocument/formatting` did not
pass bufnr to apply_text_edits, meaning edits were applied to
the user's currently active buffer. This could result in text being
applied to the wrong buffer.
ipairs terminates on the first nil index when iterating over table keys:
for i,k in ipairs( {[1] = 'test', [3] = 'test'} ) do
print(i, k)
end
prints:
1 test
Instead, use pairs which continues iterating over the entire table:
for i,k in pairs( {[1] = 'test', [3] = 'test'} ) do
print(i, k)
end
prints:
1 test
3 test
`return err_message(tostring(err))` caused errors to be printed as
`table: 0x123456789` instead of showing the error code and error
message.
This also removes some `if err` blocks that never got called because at
the end of `handlers.lua` all the handlers are wrapped with logic that
adds generic error handling.
RFC 8089, which defines the file URI scheme, also allows URIs without a
hostname, i.e. of the form file:/path/to/file. These are returned by
some language servers and accepted by other LSP implementations, such as
VSCode's, so it is reasonable for us to accept them as well.
Adds indentation that matches the number prefix to ensure diagnostic
messages spawning multiple lines align.
Before:
Diagnostics:
1. • Variable not in scope: red :: t0 -> t
• Perhaps you meant one of these:
‘rem’ (imported from Prelude), ‘read’ (imported from Prelude),
‘pred’ (imported from Prelude)
2. • Variable not in scope: repeDoubleColon :: [Char] -> t0
• Perhaps you meant ‘replaceDoubleColon’ (line 32)
After:
Diagnostics:
1. • Variable not in scope: red :: t0 -> t
• Perhaps you meant one of these:
‘rem’ (imported from Prelude), ‘read’ (imported from Prelude),
‘pred’ (imported from Prelude)
2. • Variable not in scope: repeDoubleColon :: [Char] -> t0
• Perhaps you meant ‘replaceDoubleColon’ (line 32)
Options formatted as a list of comma-separated key-value pairs may have
values that contain leading and trailing whitespace characters. For
example, the `listchars` option has a default value of
`"tab:> ,trail:-,nbsp:+"`. When converting this value to a lua table,
leading and trailing whitespace should not be trimmed.
Co-authored-by: Robert Hrusecky <robert.hrusecky@utexas.edu>
This closes#14677, but I also am a little unsure if there are times
where this may not be correct. However, this just changes the behavior
that even if `was_set` was false, we still get for
`nvim_win_get_option`.
The `onexit` handler could set `message_callbacks` to `nil` within the
luv event loop while the mainloop runs a function that tries to access
`message_callbacks`.
This adds some checks to prevent errors in that case.
Fixes https://github.com/neovim/neovim/issues/14863
Add the buffer number to the `textDocument/formatting` request, so
that it is passed to the handler.
The built-in formatting handlers do not use the buffer number, but user
overrides should have access to it.
`lsp.diagnostic.get_all()` was returning diagnotics for `:bwipeout`-ed
buffers because the diagnostic cache is not cleared. The first argument
of on_detach callback is the string "detach", not the bufnr.
Currently, for large number of diagnostics, the delay in populating
loclist may be sufficient for a user to switch to another window,
resulting in the loclist being populated on the wrong window.
In the documentation for `vim.lsp.util.open_floating_preview`
the opts table keys were prefixed with `--` instead of `---`,
preventing capture by docgen.
This pr allows the user to specify whether `lsp.utils.open_floating_preview`
is focusable via the `opts` parameter. Defaults to true.
It can be configured by setting the focusable key inside opts parameter:
```lua
vim.lsp.util.open_floating_preview(contents, syntax, {focusable = false})
```
handlers passed to `lsp_buf_request` weren't called if the server
responded with an error that looks like this:
"decoded", {
error = {
code = -32601,
message = "No delegateCommandHandler for foo"
},
id = 5,
jsonrpc = "2.0"
}
An example where that happens is both eclipse.jdt.ls and the
haskell-language-server when invoking a command that doesn't exist:
:lua vim.lsp.buf_request(
0,
'workspace/executeCommand',
{ command = 'foo' },
function(err, _, res)
print(vim.inspect(err), vim.inspect(res))
end
)
fix: fancy_floating_markdown: syn region must include keepend to make sure syntax regions are applied correctly. Fixes#14594
feat: fancy_floating_markdown: handle <pre></pre> code blocks as a markdown code block with plaintext
fix: possible nil check for markdown code blocks till end of buffer
refactor: only one check is needed to see if stripped[h.finish +1] is valid
fix(lsp): dont't set doc ownsyntax, since it breaks contained syntaxes. Set regions for the markdown blocks intsead
fix: apply markdown formatting for code blocks without a language
fix: use markdownCodeBlock when no language was set in a code block
Unfortunately, there are some subtle bugs in the smarter tagstack changes,
so we'll revert them for now and try to come up with a better approach.
One of the added tests, adds current position to jumplist before jumping,
is valuable though and changed to still work after reverting the other two
commits.
Closes#14571
For the case of Clojure and other Lisp syntax highlighting, it is
necessary to create huge regexps consisting of hundreds of symbols with
the pipe (|) character. To make things more difficult, these Lisp
symbols sometimes consists of special characters that are themselves
part of special regexp characters like '*'. In addition to being
difficult to maintain, it's performance is suboptimal.
This patch introduces a new predicate to perform 'source' matching in
amortized constant time. This is accomplished by compiling a hash table
on the first use.
Some servers might respond to `workspace/executeCommand` requests with a
boolean result and that could be `false`.
A `false` result should be allowed and not trigger the `on_error`
handler:
-- Invalid server message
on_error(client_errors.INVALID_SERVER_MESSAGE, decoded)
Concrete example where this occurred is with eclipse.jdt.ls:
vim.lsp.buf_request(
0,
'workspace/executeCommand',
{
command = 'java.project.isTestFile',
arguments = { vim.uri_from_bufnr(0), },
},
function(err, _, resp)
print(vim.inspect(err), vim.inspect(resp))
end
)
This commit prevents two things regarding the tagstack and jumping to
locations:
- Pushing the same item twice in a row
- Pushing an item where the destination is the same as the source
Both prevent having to press CTRL-T additional times just to pop items
that don't make the cursor move.
This reverts commit 2e6c09838f.
* Fixes#14428
* This commit caused neovim to close while open handles to the uv timer
to kill active language servers were still open
Allow to sort diagnostics (and thus signs and virtual text) by severity, so that
the most important message is shown first.
vim.lsp.handlers['textDocument/publishDiagnostics'] = vim.lsp.with(
vim.lsp.diagnostic.on_publish_diagnostics, {
severity_sort = true,
}
)
Fixes https://github.com/neovim/neovim/issues/13929
This is maybe a bit of a niche case, but I hit on this often as I'm
developing a server, and therefore continually restarting it to get the
latest changes of the server. Previously, I could only do this once
since if you send in a request to restart/shut down the server, it will
register it as a `tried_graceful_shutdown = true` meaning that the next
restart would force it to be killed instead of another graceful exit.
Instead, this changes the name a bit and now it will only mark
`graceful_shutdown_failed = true` _if_ it actually fails to gracefully
shutdown. This change allows for a user to restart multiple times in a
situation like mine where nothing is going wrong, but I just want to
restart continually as I'm developing without having to close and
reopen.
If vim.lsp.log is loaded the second time,
the vim.log.levels will be modified with additional
entries from 0-5.
This will cause the require to fail as level:lower does
not exists on numbered value.
There were a couple of reports of "Buffer X newer than edits" problems.
We first assumed that it is incorrect for a server to send 0 as a
version - and stated that they should send a `null` instead, given that
in the specification the `textDocument` of a `TextDocumentEdit` is a
`OptionalVersionedTextDocumentIdentifier`.
But it turns out that this was a change in 3.16, and in 3.15 and earlier
versions of the specification it was a `VersionedTextDocumentIdentifier`
and language servers didn't have a better option than sending `0` if
they don't keep track of the version numbers.
So this changes the version check to always accept `0` values.
See
- https://github.com/neovim/neovim/issues/12970
- https://github.com/neovim/neovim/issues/14256
- https://github.com/haskell/haskell-language-server/pull/1727
Because borders add up to 2 to the height of a float, we need to subtract that
from the anchor position, when opening a float in the lower half of the window.