lsp: add $/progress report (#13294)

Heavily inspired by https://github.com/nvim-lua/lsp-status.nvim.
listen to the LspProgressUpdate event to update your statusline.
This commit is contained in:
Matthieu Coudron 2020-12-20 21:59:25 +01:00 committed by GitHub
parent b1711e6f92
commit 1e59134834
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 103 additions and 0 deletions

View File

@ -569,6 +569,8 @@ function lsp.start_client(config)
-- TODO(remove-callbacks) -- TODO(remove-callbacks)
callbacks = handlers; callbacks = handlers;
handlers = handlers; handlers = handlers;
-- for $/progress report
messages = { name = name, messages = {}, progress = {}, status = {} }
} }
-- Store the uninitialized_clients for cleanup in case we exit before initialize finishes. -- Store the uninitialized_clients for cleanup in case we exit before initialize finishes.

View File

@ -24,6 +24,47 @@ M['workspace/executeCommand'] = function(err, _)
end end
end end
-- @msg of type ProgressParams
-- Basically a token of type number/string
local function progress_callback(_, _, params, client_id)
local client = vim.lsp.get_client_by_id(client_id)
if not client then
err_message("LSP[", client_id, "] client has shut down after sending the message")
end
local val = params.value -- unspecified yet
local token = params.token -- string or number
if val.kind then
if val.kind == 'begin' then
client.messages.progress[token] = {
title = val.title,
message = val.message,
percentage = val.percentage,
}
elseif val.kind == 'report' then
client.messages.progress[token] = {
message = val.message,
percentage = val.percentage,
}
elseif val.kind == 'end' then
if client.messages.progress[token] == nil then
err_message(
'echom "[lsp-status] Received `end` message with no corresponding `begin` from "')
else
client.messages.progress[token].message = val.message
client.messages.progress[token].done = true
end
end
else
table.insert(client.messages, {content = val, show_once = true, shown = 0})
end
vim.api.nvim_command("doautocmd User LspProgressUpdate")
end
M['$/progress'] = progress_callback
--@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction --@see https://microsoft.github.io/language-server-protocol/specifications/specification-current/#textDocument_codeAction
M['textDocument/codeAction'] = function(_, _, actions) M['textDocument/codeAction'] = function(_, _, actions)
if actions == nil or vim.tbl_isempty(actions) then if actions == nil or vim.tbl_isempty(actions) then

View File

@ -728,6 +728,9 @@ function protocol.make_client_capabilities()
dynamicRegistration = false; dynamicRegistration = false;
}; };
experimental = nil; experimental = nil;
window = {
workDoneProgress = true;
}
} }
end end

View File

@ -120,6 +120,63 @@ local function get_line_byte_from_position(bufnr, position)
return col return col
end end
--- Process and return progress reports from lsp server
function M.get_progress_messages()
local new_messages = {}
local msg_remove = {}
local progress_remove = {}
for _, client in ipairs(vim.lsp.get_active_clients()) do
local messages = client.messages
local data = messages
for token, ctx in pairs(data.progress) do
local new_report = {
name = data.name,
title = ctx.title or "empty title",
message = ctx.message,
percentage = ctx.percentage,
progress = true,
}
table.insert(new_messages, new_report)
if ctx.done then
table.insert(progress_remove, {client = client, token = token})
end
end
for i, msg in ipairs(data.messages) do
if msg.show_once then
msg.shown = msg.shown + 1
if msg.shown > 1 then
table.insert(msg_remove, {client = client, idx = i})
end
end
table.insert(new_messages, {name = data.name, content = msg.content})
end
if next(data.status) ~= nil then
table.insert(new_messages, {
name = data.name,
content = data.status.content,
uri = data.status.uri,
status = true
})
end
for _, item in ipairs(msg_remove) do
table.remove(client.messages, item.idx)
end
for _, item in ipairs(progress_remove) do
client.messages.progress[item.token] = nil
end
end
return new_messages
end
--- Applies a list of text edits to a buffer. --- Applies a list of text edits to a buffer.
--@param text_edits (table) list of `TextEdit` objects --@param text_edits (table) list of `TextEdit` objects
--@param buf_nr (number) Buffer id --@param buf_nr (number) Buffer id