aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/lsp.txt51
-rw-r--r--runtime/doc/news.txt6
-rw-r--r--runtime/lua/vim/lsp.lua27
-rw-r--r--src/nvim/auevents.lua2
-rw-r--r--test/functional/plugin/lsp_spec.lua2
5 files changed, 75 insertions, 13 deletions
diff --git a/runtime/doc/lsp.txt b/runtime/doc/lsp.txt
index 98a0801013..581cfd5348 100644
--- a/runtime/doc/lsp.txt
+++ b/runtime/doc/lsp.txt
@@ -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
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt
index b6839ec692..72eb182fa5 100644
--- a/runtime/doc/news.txt
+++ b/runtime/doc/news.txt
@@ -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*
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 5337abea25..c9ca8cd224 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -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
diff --git a/src/nvim/auevents.lua b/src/nvim/auevents.lua
index aef08be820..048b8d6631 100644
--- a/src/nvim/auevents.lua
+++ b/src/nvim/auevents.lua
@@ -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,
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
index 1a7a656d1d..e0ce62c0db 100644
--- a/test/functional/plugin/lsp_spec.lua
+++ b/test/functional/plugin/lsp_spec.lua
@@ -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'))