Most LSP servers require the notification to correctly load the
settings and for those who don't it doesn't cause any harm.
So far this is done in lspconfig, but with the addition of vim.lsp.start
it should be part of core.
A alternative/subset of https://github.com/neovim/neovim/pull/18506 that should be forward compatible with a potential project system.
Configuration of LSP clients (without lspconfig) now looks like this:
vim.lsp.start({
name = 'my-server-name',
cmd = {'name-of-language-server-executable'},
root_dir = vim.fs.dirname(vim.fs.find({'setup.py', 'pyproject.toml'}, { upward = true })[1]),
})
The client state is cleaned up both in client.stop() as well as in the
client.on_exit() handler. Technically, the client has not actually
stopped until the on_exit handler is called, so we should just do this
cleanup there and remove it from client.stop().
The current approach of using `on_attach` callbacks for configuring
buffers for LSP is suboptimal:
1. It does not use the standard Nvim interface for driving and hooking
into events (i.e. autocommands)
2. There is no way for "third parties" (e.g. plugins) to hook into the
event. This means that *all* buffer configuration must go into the
user-supplied on_attach callback. This also makes it impossible for
these configurations to be modular, since it all must happen in the
same place.
3. There is currently no way to do something when a client detaches from
a buffer (there is no `on_detach` callback).
The solution is to use the traditional method of event handling in Nvim:
autocommands. When a LSP client is attached to a buffer, fire a
`LspAttach`. Likewise, when a client detaches from a buffer fire a
`LspDetach` event.
This enables plugins to easily add LSP-specific configuration to buffers
as well as enabling users to make their own configurations more modular
(e.g. by creating multiple LspAttach autocommands that each do
something unique).
LSP servers should be daemonized (detached) so that they run in a
separate process group from Neovim's. Among other things, this ensures
the process does not inherit Neovim's TTY (#18475).
Make this configurable so that clients can explicitly opt-out of
detaching from Nvim.
* feat(lsp)!: remove capabilities sanitization
Users must now access client.server_capabilities which matches the same
structure as the protocol.
https://microsoft.github.io/language-server-protocol/specification
client.resolved_capabilities is no longer used to gate capabilities, and
will be removed in a future release.
BREAKING CHANGE
Co-authored-by: Mathias Fussenegger <f.mathias@zignar.net>
LSP server might return an item which would replace a token to another.
For example in typescript for a `jest.Mock` object `getProductsMock.`
text I get the following response:
```
{
commitCharacters = {
".",
",",
"("
},
data = {
entryNames = {
"Symbol"
},
file = "/foo/bar/baz.service.spec.ts",
line = 268,
offset = 17
},
filterText = ".Symbol",
kind = 6,
label = "Symbol",
sortText = "11",
textEdit = {
newText = "[Symbol]",
range = {
end = {
character = 16,
line = 267
},
start = {
character = 15,
line = 267
}
}
}
},
```
In `lsp.omnifunc` to get a `prefix` we call the `adjust_start_col` which
then returns the `textEdit.range.start.character`.
Th `prefix` then be the `.` character. Then when filter the items with
`remove_unmatch_completion_items`, every item will be filtered out,
since no completion word starts `.`.
To fix we return the `end.character`, which in that particular case will
be the position after the `.`.
This commits introduces two performance improvements in incremental sync:
* avoiding expensive lua string reallocations on each on_lines call by requesting
only the changed chunk of the buffer as reported by firstline and new_lastline
parameters of on_lines
* re-using already allocated tables for storing the resulting lines to reduce the load on
the garbage collector
The majority of the performance improvement is from requesting only changed chunks
of the buffer.
Benchmark:
The following code measures the time required to perform a buffer edit to
that operates individually on each line, common to plugins such as vim-commentary.
set rtp+=~/.config/nvim/plugged/nvim-lspconfig
set rtp+=~/.config/nvim/plugged/vim-commentary
lua require('lspconfig')['ccls'].setup({})
function! Benchmark(tries) abort
let results_comment = []
let results_undo = []
for i in range(a:tries)
echo printf('run %d', i+1)
let begin = reltime()
normal gggcG
call add(results_comment, reltimefloat(reltime(begin)))
let begin = reltime()
silent! undo
call add(results_undo, reltimefloat(reltime(begin)))
redraw
endfor
let avg_comment = 0.0
let avg_undo = 0.0
for i in range(a:tries)
echomsg printf('run %3d: comment=%fs undo=%fs', i+1, results_comment[i], results_undo[i])
let avg_comment += results_comment[i]
let avg_undo += results_undo[i]
endfor
echomsg printf('average: comment=%fs undo=%fs', avg_comment / a:tries, avg_undo / a:tries)
endfunction
command! -bar Benchmark call Benchmark(10)
All text changes will be recorded within a single undo operation. Both the
comment operation itself and the undo operation will generate an on_lines event
for each changed line. Formatter plugins using setline() have also been found
to exhibit the same problem (neoformat, :RustFmt in rust.vim), as this function
too generates an on_lines event for every line it changes.
Using the neovim codebase as an example (commit 2ecf0a4)
with neovim itself built at 2ecf0a4 with
CMAKE_BUILD_TYPE=Release shows the following performance improvement:
src/nvim/lua/executor.c, 1432 lines:
- baseline, no optimizations: comment=0.540587s undo=0.440249s
- without double-buffering optimization: comment=0.183314s undo=0.060663s
- all optimizations in this commit: comment=0.174850s undo=0.052789s
src/nvim/search.c, 5467 lines:
- baseline, no optimizations: comment=7.420446s undo=7.656624s
- without double-buffering optimization: comment=0.889048s undo=0.486026s
- all optimizations in this commit: comment=0.662899s undo=0.243628s
src/nvim/eval.c, 11355 lines:
- baseline, no optimizations: comment=41.775695s undo=44.583374s
- without double-buffering optimization: comment=3.643933s undo=2.817158s
- all optimizations in this commit: comment=1.510886s undo=0.707928s
Co-authored-by: Dmytro Meleshko <dmytro.meleshko@gmail.com>
Part of the `pending_change` closure in the `changetracking.prepare` was
a bit confusing because it has access to `bufnr` and `uri` but it could
actually contain pending changes batched for multiple buffers.
(We accounted for that by grouping `pending_changes` by a `uri`, but
it's not obvious what's going on)
This commit changes the approach to do everything per buffer to avoid
any ambiguity.
It also brings the debounce/no-debounce a bit closer together: The
only difference is now whether a timer is used or if it is triggered
immediately
Follow up to https://github.com/neovim/neovim/pull/16881
Document changes could get sent out of order to the server:
1. on_lines: debounce > 0; add to pending changes; setup timer
2. on_lines: debounce = 0; send new changes immediately
3. timer triggers, sending changes from 1.
The idea of the debounce is to avoid overloading a server with didChange
notifications. So far this used a constant value to group changes within
an interval together and send a single notification. A side effect of
this is that when you were idle, notifications are still delayed.
This commit changes the logic to take the time the last notification
happened into consideration, if it has been greater than the debounce
interval, the debouncing is skipped or at least reduced.
Co-authored-by: Sean Dewar <seandewar@users.noreply.github.com>
Co-authored-by: Gregory Anders <greg@gpanders.com>
Co-authored-by: Sebastian Volland <seb@baunz.net>
Co-authored-by: Lewis Russell <lewis6991@gmail.com>
Co-authored-by: zeertzjq <zeertzjq@outlook.com>
This allows the user to detach an active buffer from the language
client. If no clients remain attached to a buffer, the on_lines callback
is used to cancel nvim_buf_attach.
Closes https://github.com/neovim/neovim/issues/16562https://github.com/neovim/neovim/issues/16249https://github.com/neovim/neovim/issues/16297
* buf_attach_client can be called on an unloaded buffer
* on_attach will prematurely fail, while the language server client
tracks this buffer as attached
* The language server client will track this buffer as attached despite
textDocument/didChange notifications not being sent to the server
* Instead, check if the buffer is loaded and return early, warning via
the lsp logger that buf_attach_client was called on an invalid buffer
The on_exit handler provided to the client configuration is called after
the client's context is cleared (e.g. which buffers the client was
attached to). Calling the handler sooner allows these handlers to access
the client object and do their own cleanup with the full context.
Previously, the built-in language server client checked if the first
argument of cmd was executable via vim.fn.executable. This ignores PATH
injected via cmd_env. Instead, we now start the client via uv.spawn, and
handle the failure mode, reporting the error back to the user.
Co-authored-by: Mathias Fußenegger <mfussenegger@users.noreply.github.com>
If a LSP server sent a workspace edit containing a rename the buffers
file name changed without the server receiving a close notification for
the old buffer and without the client properly re-attaching on the new
file.
This affected `Move` code-actions in nvim-jdtls, but also
`vim.lsp.buf.rename` on a class level.
* use codeunits/points instead of byte ranges when applicable
* take into account different file formats when computing range and
sending text (dos, unix, and mac supported)
* add tests of incremental sync
Fixes a bug introduced by https://github.com/neovim/neovim/pull/15949
When no supported clients for a given method are available, buf_request
returns early with a nil value. If buf_request_sync is called on a
buffer with no clients that support a given method, the returned
`cancel` method (which is nil), is invoked, resulting in an error.
Solution: return an empty function handle
* This flag allows customizing the time before sending kill -15 to the
server. If set to false, neovim exits immediately after sending
request('shutdown'). Otherwise, polls until all servers have shutdown,
and then kills remaining servers via kill -15 at exit_timeout
duration. Defaults to 500 ms.
closes https://github.com/neovim/neovim/issues/16058
* add client.attached_buffers
* only update client.attached_buffers in on_attach
* use table instead of list for attached_buffers to avoid duplication
The spacing fix drew attention to a couple of places that were using
incorrect formatting such as the key listing for `nvim_open_win`, so
those were fixed too.
Closes https://github.com/neovim/neovim/issues/15174
Instead of invoking handlers with unsupported methods, pre-compute which
clients support a given method and only notify the user if no clients
support the given method.
This is a simple fix for #15899, as it should at least stop calling
`prepareRename` on servers that don't support renaming.
I imagine a better fix would be to inspect the actual value for, but
that requires some plumbing changes on how capabilities are evaluated
before sending requests out.
Co-authored-by: francisco souza <fsouza@users.noreply.github.com>
This is mostly motivated by https://github.com/neovim/neovim/issues/12326
Client side commands might need to access the original request
parameters.
Currently this is already possible by using closures with
`vim.lsp.buf_request`, but the global handlers so far couldn't access
the request parameters.
## Overview
- Move vim.lsp.diagnostic to vim.diagnostic
- Refactor client ids to diagnostic namespaces
- Update tests
- Write/update documentation and function signatures
Currently, non-LSP diagnostics in Neovim must hook into the LSP subsystem. This
is what e.g. null-ls and nvim-lint do. This is necessary because none of the
diagnostic API is exposed separately from the LSP subsystem.
This commit addresses this by generalizing the diagnostic subsystem beyond the
scope of LSP. The `vim.lsp.diagnostic` module is now simply a specific
diagnostic producer and primarily maintains the interface between LSP clients
and the broader diagnostic API.
The current diagnostic API uses "client ids" which only makes sense in the
context of LSP. We replace "client ids" with standard API namespaces generated
from `nvim_create_namespace`.
This PR is *mostly* backward compatible (so long as plugins are only using the
publicly documented API): LSP diagnostics will continue to work as usual, as
will pseudo-LSP clients like null-ls and nvim-lint. However, the latter can now
use the new interface, which looks something like this:
```lua
-- The namespace *must* be given a name. Anonymous namespaces will not work with diagnostics
local ns = vim.api.nvim_create_namespace("foo")
-- Generate diagnostics
local diagnostics = generate_diagnostics()
-- Set diagnostics for the current buffer
vim.diagnostic.set(ns, diagnostics, bufnr)
```
Some public facing API utility methods were removed and internalized directly in `vim.diagnostic`:
* `vim.lsp.util.diagnostics_to_items`
## API Design
`vim.diagnostic` contains most of the same API as `vim.lsp.diagnostic` with
`client_id` simply replaced with `namespace`, with some differences:
* Generally speaking, functions that modify or add diagnostics require a namespace as their first argument, e.g.
```lua
vim.diagnostic.set({namespace}, {bufnr}, {diagnostics}[, {opts}])
```
while functions that read or query diagnostics do not (although in many cases one may be supplied optionally):
```lua
vim.diagnostic.get({bufnr}[, {namespace}])
```
* We use our own severity levels to decouple `vim.diagnostic` from LSP. These
are designed similarly to `vim.log.levels` and currently include:
```lua
vim.diagnostic.severity.ERROR
vim.diagnostic.severity.WARN
vim.diagnostic.severity.INFO
vim.diagnostic.severity.HINT
```
In practice, these match the LSP diagnostic severity levels exactly, but we
should treat this as an interface and not assume that they are the same. The
"translation" between the two severity types is handled transparently in
`vim.lsp.diagnostic`.
* The actual "diagnostic" data structure is: (**EDIT:** Updated 2021-09-09):
```lua
{
lnum = <number>,
col = <number>,
end_lnum = <number>,
end_col = <number>,
severity = <vim.diagnostic.severity>,
message = <string>
}
```
This differs from the LSP definition of a diagnostic, so we transform them in
the handler functions in vim.lsp.diagnostic.
## Configuration
The `vim.lsp.with` paradigm still works for configuring how LSP diagnostics are
displayed, but this is a specific use-case for the `publishDiagnostics` handler.
Configuration with `vim.diagnostic` is instead done with the
`vim.diagnostic.config` function:
```lua
vim.diagnostic.config({
virtual_text = true,
signs = false,
underline = true,
update_in_insert = true,
severity_sort = false,
}[, namespace])
```
(or alternatively passed directly to `set()` or `show()`.)
When the `namespace` argument is `nil`, settings are set globally (i.e. for
*all* diagnostic namespaces). This is what user's will typically use for their
local configuration. Diagnostic producers can also set configuration options for
their specific namespace, although this is generally discouraged in order to
respect the user's global settings. All of the values in the table passed to
`vim.diagnostic.config()` are resolved in the same way that they are in
`on_publish_diagnostics`; that is, the value can be a boolean, a table, or
a function:
```lua
vim.diagnostic.config({
virtual_text = function(namespace, bufnr)
-- Only enable virtual text in buffer 3
return bufnr == 3
end,
})
```
## Misc Notes
* `vim.diagnostic` currently depends on `vim.lsp.util` for floating window
previews. I think this is okay for now, although ideally we'd want to decouple
these completely.
This generalizes diagnostic handling outside of just the scope of LSP.
LSP clients are now a specific case of a diagnostic producer, but the
diagnostic subsystem is decoupled from the LSP subsystem (or will be,
eventually).
More discussion at [1].
[1]: https://github.com/neovim/neovim/pull/15585
* Simplify rpc encode/decode messages to rpc.send/rcp.receive
* Make missing handlers message throw a warning
* Clean up formatting style in log
* Move all non-RPC loop messages to trace instead of debug
* Add format func option to log to allow newlines in per log entry
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
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.
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.
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.
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
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.
With the new implementation added in
https://github.com/neovim/neovim/pull/14079 I think this is now working
well enough to enable it by default.
There are high CPU usage issues popping up now and then and they might
at least partially be related to the full-text sync.
* Allow specifying a languageId for a lsp
For some languages the filetype might not match the languageId the
language server accepts. In these cases the config for the language
server can contain a function which gets the current buffer and filetype
and returns a languageId. When it isn't provided the filetype is used
instead.
Example:
```lua
require'lspconfig'.sourcekit.setup{
get_language_id = function(bufnr, ft)
return 'swift'
end;
}
```
Closes#13093
* lsp: Change to get_language_id
Co-authored-by: Jan Dammshäuser <mail@jandamm.de>
* lsp: client stop cleanups
* Add diagnostic clearing to client.stop() method used by nvim-lspconfig
* Clear diagnostic cache to prevent stale diagnostics on client restart
* lsp: Add test for vim.lsp.diagnostic.reset
We should be consistent in sending the EOL character to servers(I think). Julia expects this to match on bufwrite, or it crashes when vim appends the newline during the write process.
The `workspace/configuration` handler could fail with the following
error if `config.settings` is nil:
runtime/lua/vim/lsp/util.lua:1432: attempt to index local 'settings' (a nil value)"
This ensures that `config.settings` is always initialized to an empty
table.
* Add in clienInfo to initalize_params.
Some servers (like Metals in my case) will actually pull this
info from the initalize_params and display it in the logs. I
know from the server perspective it helps at times to have this
available to pull from to have more details about the client and
version. You can see that this is part of the spec here:
microsoft.github.io/language-server-protocol/specification#initialize
According to the specification[1] the payload must look like this:
interface DidSaveTextDocumentParams {
/**
* The document that was saved.
*/
textDocument: TextDocumentIdentifier;
/**
* Optional the content when saved. Depends on the includeText value
* when the save notification was requested.
*/
text?: string;
}
`text` must be on the same level as `textDocument´.
Where `TextDocumentIdentifier` is:
interface TextDocumentIdentifier {
/**
* The text document's URI.
*/
uri: DocumentUri;
}
[1]: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_didSave
* First implementation of workspace folders
* Add completion for current directory
* Add tracking of workspace folders
* Add workspace folder listing
* Add checks on adding/removing workspaces
* Add appropriate initialization options
* Add documentation
* Make workspaceFolders available wherever client is
Breaking Changes:
- Deprecated all `vim.lsp.util.{*diagnostics*}()` functions.
- Instead, all functions must be found in vim.lsp.diagnostic
- For now, they issue a warning ONCE per neovim session. In a
"little while" we will remove them completely.
- `vim.lsp.callbacks` has moved to `vim.lsp.handlers`.
- For a "little while" we will just redirect `vim.lsp.callbacks` to
`vim.lsp.handlers`. However, we will remove this at some point, so
it is recommended that you change all of your references to
`callbacks` into `handlers`.
- This also means that for functions like |vim.lsp.start_client()|
and similar, keyword style arguments have moved from "callbacks"
to "handlers". Once again, these are currently being forward, but
will cease to be forwarded in a "little while".
- Changed the highlight groups for LspDiagnostic highlight as they were
inconsistently named.
- For more information, see |lsp-highlight-diagnostics|
- Changed the sign group names as well, to be consistent with
|lsp-highlight-diagnostics|
General Enhancements:
- Rewrote much of the getting started help document for lsp. It also
provides a much nicer configuration strategy, so as to not recommend
globally overwriting builtin neovim mappings.
LSP Enhancements:
- Introduced the concept of |lsp-handlers| which will allow much better
customization for users without having to copy & paste entire files /
functions / etc.
Diagnostic Enhancements:
- "goto next diagnostic" |vim.lsp.diagnostic.goto_next()|
- "goto prev diagnostic" |vim.lsp.diagnostic.goto_prev()|
- For each of the gotos, auto open diagnostics is available as a
configuration option
- Configurable diagnostic handling:
- See |vim.lsp.diagnostic.on_publish_diagnostics()|
- Delay display until after insert mode
- Configure signs
- Configure virtual text
- Configure underline
- Set the location list with the buffers diagnostics.
- See |vim.lsp.diagnostic.set_loclist()|
- Better performance for getting counts and line diagnostics
- They are now cached on save, to enhance lookups.
- Particularly useful for checking in statusline, etc.
- Actual testing :)
- See ./test/functional/plugin/lsp/diagnostic_spec.lua
- Added `guisp` for underline highlighting
NOTE: "a little while" means enough time to feel like most plugins and
plugin authors have had a chance to refactor their code to use the
updated calls. Then we will remove them completely. There is no need to
keep them, because we don't have any released version of neovim that
exposes these APIs. I'm trying to be nice to people following HEAD :)
Co-authored: [Twitch Chat 2020](https://twitch.tv/teej_dv)
Refactors how required capabilities are detected and validated, and make
sure requests are only sent to clients that support it (and only fail if
no clients support the provided method).
The validation happens at the buf_request level, because we assume that
if someone is sending the request directly through the client, they know
what they're doing. Also, let unknown methods go through.
This is extracted from #12518 and closes#12755.
Co-authored-by: francisco souza <fsouza@users.noreply.github.com>
Language servers can already send log messages to the client while the
server is still being initialized.
This currently leads to "client has shut down" messages which are
confusing to the user as the server is properly starting.
To fix this this changes the `get_client_by_id` method to also return a
client if it is still initializing.
- remove redundant autocmd list
This "grouped" list is useless, it only gets in the way when searching
for event names.
- intro.txt: cleanup
- starting.txt: update, revisit
- doc: `:help bisect`
- mbyte.txt: update aliases 1656367b90. closes#11960
- options: remove 'guifontset'. Why:
- It is complicated and is used by almost no one.
- It is unlikely to be implemented by Nvim GUIs (complicated to parse,
specific to Xorg...).
* LSP: Add support for call hierarchies
* LSP: Add support for call hierarchies
* LSP: Add support for call hierarchies
* LSP: Jump to call location
Jump to the call site instead of jumping to the definition of the
caller/callee.
* LSP: add tests for the call hierarchy callbacks
* Fix linting error
Co-authored-by: Cédric Barreteau <>
* Fix some small doc issues
* doc: fixup
* doc: fixup
* Fix lint and rebase
* Remove bad advice
* Ugh, stupid mpack files...
* Don't let people include these for now until they specifically want to
* Prevent duplicate tag
* Add check for typeDefinition support in vim lsp server
* Check for typeDefinitionProvider in server
* Check for declarationProvider in server
* Add check for client support
* Fix typo
* lsp: add workspace/symbol
* refactor symbol callback
* set hierarchical symbol support to true
* add documentation and default mapping
Co-authored-by: Hirokazu Hata <h.hata.ai.t@gmail.com>
This commit creates 4 new highlight groups:
- LspDiagnosticsErrorSign
- LspDiagnosticsWarningSign
- LspDiagnosticsInformationSign
- LspDiagnosticsHintSign
These highlight groups are linked to their corresponding LspDiagnostics
highlight groups by default.
This lets users choose a different color for their sign columns and
virtualtext diagnostics.
fix: #11826
Some lanuguage servers return complementary candidates whose prefixes do not match are also returned.
So we exclude completion candidates whose prefix does not match.
ex) Microsoft python-language-server, rust-analyzer
Reduce API surface. We don't need so many variations of functions. Too
many functions means verbose, largely redundant documentation, tests,
and cognitive burden.
- In the process, refactored focusable_preview to a util function.
- Add text for locations_to_items of the current line.
- Improve location callback to handle multiple return values by using
set_qflist.
- Remove update_tagstack and leave note for future travelers.