diff options
Diffstat (limited to 'runtime/lua/vim')
-rw-r--r-- | runtime/lua/vim/lsp.lua | 2 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/handlers.lua | 41 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/protocol.lua | 3 | ||||
-rw-r--r-- | runtime/lua/vim/lsp/util.lua | 57 |
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 |