mirror of
https://github.com/neovim/neovim.git
synced 2024-12-23 12:45:17 -07:00
feat(lsp)!: promote LspRequest to a full autocmd and enrich with additional data (#23694)
BREAKING CHANGE: LspRequest is no longer a User autocmd but is now a first class citizen. LspRequest as a User autocmd had limited functionality. Namely, the only thing you could do was use the notification to do a lookup on all the clients' requests tables to figure out what changed. Promoting the autocmd to a full autocmd lets us set the buffer the request was initiated on (so people can set buffer-local autocmds for listening to these events). Additionally, when used from Lua, we can pass additional metadata about the request along with the notification, including the client ID, the request ID, and the actual request object stored on the client's requests table. Users can now listen for these events and act on them proactively instead of polling all of the requests tables and looking for changes.
This commit is contained in:
parent
dd3fa64573
commit
58618d208a
@ -619,19 +619,54 @@ to the callback in the "data" table. The token fields are documented in
|
||||
Note: doing anything other than calling
|
||||
|vim.lsp.semantic_tokens.highlight_token()| is considered experimental.
|
||||
|
||||
Also the following |User| |autocommand|s are provided:
|
||||
|
||||
LspRequest *LspRequest*
|
||||
|
||||
For each request sent to an LSP server, this event is triggered for every
|
||||
change to the request's status. The status can be one of `pending`,
|
||||
`complete`, or `cancel` and is sent as the {type} on the "data" table passed
|
||||
to the callback function.
|
||||
|
||||
It triggers when the initial request is sent ({type} == `pending`) and when
|
||||
the LSP server responds ({type} == `complete`). If a cancelation is requested
|
||||
using `client.cancel_request(request_id)`, then this event will trigger with
|
||||
{type} == `cancel`.
|
||||
|
||||
When used from Lua, the client ID, request ID, and request are sent in the
|
||||
"data" table. See {requests} in |vim.lsp.client| for details on the {request}
|
||||
value. If the request type is `complete`, the request will be deleted from the
|
||||
client's pending requests table immediately after calling the event's
|
||||
callbacks. Example: >lua
|
||||
|
||||
vim.api.nvim_create_autocmd('LspRequest', {
|
||||
callback = function(args)
|
||||
local bufnr = args.buf
|
||||
local client_id = args.data.client_id
|
||||
local request_id = args.data.request_id
|
||||
local request = args.data.request
|
||||
if request.type == 'pending' then
|
||||
-- do something with pending requests
|
||||
track_pending(client_id, bufnr, request_id, request)
|
||||
elseif request.type == 'cancel' then
|
||||
-- do something with pending cancel requests
|
||||
track_canceling(client_id, bufnr, request_id, request)
|
||||
elseif request.type == 'complete' then
|
||||
-- do something with finished requests. this pending
|
||||
-- request entry is about to be removed since it is complete
|
||||
track_finish(client_id, bufnr, request_id, request)
|
||||
end
|
||||
end,
|
||||
})
|
||||
<
|
||||
|
||||
Also the following |User| |autocommand| is provided:
|
||||
|
||||
LspProgressUpdate *LspProgressUpdate*
|
||||
Upon receipt of a progress notification from the server. See
|
||||
|vim.lsp.util.get_progress_messages()|.
|
||||
|
||||
LspRequest *LspRequest*
|
||||
After a change to the active set of pending LSP requests. See {requests}
|
||||
in |vim.lsp.client|.
|
||||
|
||||
Example: >vim
|
||||
autocmd User LspProgressUpdate redrawstatus
|
||||
autocmd User LspRequest redrawstatus
|
||||
<
|
||||
|
||||
==============================================================================
|
||||
@ -764,7 +799,9 @@ client() *vim.lsp.client*
|
||||
server. Entries are key-value pairs with the key being the request ID
|
||||
while the value is a table with `type`, `bufnr`, and `method`
|
||||
key-value pairs. `type` is either "pending" for an active request, or
|
||||
"cancel" for a cancel request.
|
||||
"cancel" for a cancel request. It will be "complete" ephemerally while
|
||||
executing |LspRequest| autocmds when replies are received from the
|
||||
server.
|
||||
• {config} (table): copy of the table that was passed by the user to
|
||||
|vim.lsp.start_client()|.
|
||||
• {server_capabilities} (table): Response from the server sent on
|
||||
|
@ -31,6 +31,9 @@ The following changes may require adaptations in user config or plugins.
|
||||
set keymodel=startsel,stopsel
|
||||
<
|
||||
|
||||
• |LspRequest| autocmd was promoted from a |User| autocmd to a first class
|
||||
citizen.
|
||||
|
||||
==============================================================================
|
||||
ADDED FEATURES *news-added*
|
||||
|
||||
@ -80,6 +83,9 @@ The following changes to existing APIs or features add new behavior.
|
||||
• The `workspace/didChangeWatchedFiles` LSP client capability is now enabled
|
||||
by default.
|
||||
|
||||
• |LspRequest| autocmd callbacks now contain additional information about the LSP
|
||||
request status update that occurred.
|
||||
|
||||
==============================================================================
|
||||
REMOVED FEATURES *news-removed*
|
||||
|
||||
|
@ -799,7 +799,9 @@ end
|
||||
--- to the server. Entries are key-value pairs with the key
|
||||
--- being the request ID while the value is a table with `type`,
|
||||
--- `bufnr`, and `method` key-value pairs. `type` is either "pending"
|
||||
--- for an active request, or "cancel" for a cancel request.
|
||||
--- for an active request, or "cancel" for a cancel request. It will
|
||||
--- be "complete" ephemerally while executing |LspRequest| autocmds
|
||||
--- when replies are received from the server.
|
||||
---
|
||||
--- - {config} (table): copy of the table that was passed by the user
|
||||
--- to |vim.lsp.start_client()|.
|
||||
@ -1408,13 +1410,24 @@ function lsp.start_client(config)
|
||||
{ method = method, client_id = client_id, bufnr = bufnr, params = params }
|
||||
)
|
||||
end, function(request_id)
|
||||
local request = client.requests[request_id]
|
||||
request.type = 'complete'
|
||||
nvim_exec_autocmds('LspRequest', {
|
||||
buffer = bufnr,
|
||||
modeline = false,
|
||||
data = { client_id = client_id, request_id = request_id, request = request },
|
||||
})
|
||||
client.requests[request_id] = nil
|
||||
nvim_exec_autocmds('User', { pattern = 'LspRequest', modeline = false })
|
||||
end)
|
||||
|
||||
if success and request_id then
|
||||
client.requests[request_id] = { type = 'pending', bufnr = bufnr, method = method }
|
||||
nvim_exec_autocmds('User', { pattern = 'LspRequest', modeline = false })
|
||||
local request = { type = 'pending', bufnr = bufnr, method = method }
|
||||
client.requests[request_id] = request
|
||||
nvim_exec_autocmds('LspRequest', {
|
||||
buffer = bufnr,
|
||||
modeline = false,
|
||||
data = { client_id = client_id, request_id = request_id, request = request },
|
||||
})
|
||||
end
|
||||
|
||||
return success, request_id
|
||||
@ -1486,7 +1499,11 @@ function lsp.start_client(config)
|
||||
local request = client.requests[id]
|
||||
if request and request.type == 'pending' then
|
||||
request.type = 'cancel'
|
||||
nvim_exec_autocmds('User', { pattern = 'LspRequest', modeline = false })
|
||||
nvim_exec_autocmds('LspRequest', {
|
||||
buffer = request.bufnr,
|
||||
modeline = false,
|
||||
data = { client_id = client_id, request_id = id, request = request },
|
||||
})
|
||||
end
|
||||
return rpc.notify('$/cancelRequest', { id = id })
|
||||
end
|
||||
|
@ -72,6 +72,7 @@ return {
|
||||
'InsertLeavePre', -- just before leaving Insert mode
|
||||
'LspAttach', -- after an LSP client attaches to a buffer
|
||||
'LspDetach', -- after an LSP client detaches from a buffer
|
||||
'LspRequest', -- after an LSP request is started, canceled, or completed
|
||||
'LspTokenUpdate', -- after a visible LSP token is updated
|
||||
'MenuPopup', -- just before popup menu is displayed
|
||||
'ModeChanged', -- after changing the mode
|
||||
@ -152,6 +153,7 @@ return {
|
||||
DiagnosticChanged=true,
|
||||
LspAttach=true,
|
||||
LspDetach=true,
|
||||
LspRequest=true,
|
||||
LspTokenUpdate=true,
|
||||
RecordingEnter=true,
|
||||
RecordingLeave=true,
|
||||
|
@ -948,7 +948,7 @@ describe('LSP', function()
|
||||
test_name = "check_tracked_requests_cleared";
|
||||
on_init = function(_client)
|
||||
command('let g:requests = 0')
|
||||
command('autocmd User LspRequest let g:requests+=1')
|
||||
command('autocmd LspRequest * let g:requests+=1')
|
||||
client = _client
|
||||
client.request("slow_request")
|
||||
eq(1, eval('g:requests'))
|
||||
|
Loading…
Reference in New Issue
Block a user