aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r--runtime/lua/vim/lsp.lua2
-rw-r--r--runtime/lua/vim/lsp/handlers.lua41
-rw-r--r--runtime/lua/vim/lsp/protocol.lua3
-rw-r--r--runtime/lua/vim/lsp/util.lua57
4 files changed, 103 insertions, 0 deletions
diff --git a/runtime/lua/vim/lsp.lua b/runtime/lua/vim/lsp.lua
index 7c7edf98e7..0326550245 100644
--- a/runtime/lua/vim/lsp.lua
+++ b/runtime/lua/vim/lsp.lua
@@ -569,6 +569,8 @@ function lsp.start_client(config)
-- TODO(remove-callbacks)
callbacks = 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.
diff --git a/runtime/lua/vim/lsp/handlers.lua b/runtime/lua/vim/lsp/handlers.lua
index e034923afb..f1dd9ef5a1 100644
--- a/runtime/lua/vim/lsp/handlers.lua
+++ b/runtime/lua/vim/lsp/handlers.lua
@@ -24,6 +24,47 @@ M['workspace/executeCommand'] = function(err, _)
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
M['textDocument/codeAction'] = function(_, _, actions)
if actions == nil or vim.tbl_isempty(actions) then
diff --git a/runtime/lua/vim/lsp/protocol.lua b/runtime/lua/vim/lsp/protocol.lua
index fd86d8bb97..b785d2f586 100644
--- a/runtime/lua/vim/lsp/protocol.lua
+++ b/runtime/lua/vim/lsp/protocol.lua
@@ -728,6 +728,9 @@ function protocol.make_client_capabilities()
dynamicRegistration = false;
};
experimental = nil;
+ window = {
+ workDoneProgress = true;
+ }
}
end
diff --git a/runtime/lua/vim/lsp/util.lua b/runtime/lua/vim/lsp/util.lua
index 3da4dd6219..0972ea83c4 100644
--- a/runtime/lua/vim/lsp/util.lua
+++ b/runtime/lua/vim/lsp/util.lua
@@ -120,6 +120,63 @@ local function get_line_byte_from_position(bufnr, position)
return col
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.
--@param text_edits (table) list of `TextEdit` objects
--@param buf_nr (number) Buffer id