diff options
-rw-r--r-- | runtime/lua/vim/lsp/codelens.lua | 11 | ||||
-rw-r--r-- | test/functional/fixtures/fake-lsp-server.lua | 42 | ||||
-rw-r--r-- | test/functional/plugin/lsp_spec.lua | 79 |
3 files changed, 129 insertions, 3 deletions
diff --git a/runtime/lua/vim/lsp/codelens.lua b/runtime/lua/vim/lsp/codelens.lua index 9eb64c9a2e..99695d2ed1 100644 --- a/runtime/lua/vim/lsp/codelens.lua +++ b/runtime/lua/vim/lsp/codelens.lua @@ -1,4 +1,5 @@ local util = require('vim.lsp.util') +local log = require('vim.lsp.log') local api = vim.api local M = {} @@ -214,7 +215,11 @@ end --- |lsp-handler| for the method `textDocument/codeLens` --- function M.on_codelens(err, result, ctx, _) - assert(not err, vim.inspect(err)) + if err then + active_refreshes[ctx.bufnr] = nil + local _ = log.error() and log.error("codelens", err) + return + end M.save(result, ctx.bufnr, ctx.client_id) @@ -222,8 +227,8 @@ function M.on_codelens(err, result, ctx, _) -- once resolved. M.display(result, ctx.bufnr, ctx.client_id) resolve_lenses(result, ctx.bufnr, ctx.client_id, function() - M.display(result, ctx.bufnr, ctx.client_id) active_refreshes[ctx.bufnr] = nil + M.display(result, ctx.bufnr, ctx.client_id) end) end @@ -245,7 +250,7 @@ function M.refresh() return end active_refreshes[bufnr] = true - vim.lsp.buf_request(0, 'textDocument/codeLens', params) + vim.lsp.buf_request(0, 'textDocument/codeLens', params, M.on_codelens) end diff --git a/test/functional/fixtures/fake-lsp-server.lua b/test/functional/fixtures/fake-lsp-server.lua index 79a29cd8d8..0418ca7335 100644 --- a/test/functional/fixtures/fake-lsp-server.lua +++ b/test/functional/fixtures/fake-lsp-server.lua @@ -792,6 +792,48 @@ function tests.clientside_commands() } end +function tests.codelens_refresh_lock() + skeleton { + on_init = function() + return { + capabilities = { + codeLensProvider = { resolveProvider = true; }; + } + } + end; + body = function() + notify('start') + expect_request("textDocument/codeLens", function () + return {code = -32002, message = "ServerNotInitialized"}, nil + end) + expect_request("textDocument/codeLens", function () + local lenses = { + { + range = { + start = { line = 0, character = 0, }, + ['end'] = { line = 0, character = 3 } + }, + command = { title = 'Lens1', command = 'Dummy' } + }, + } + return nil, lenses + end) + expect_request("textDocument/codeLens", function () + local lenses = { + { + range = { + start = { line = 0, character = 0, }, + ['end'] = { line = 0, character = 3 } + }, + command = { title = 'Lens2', command = 'Dummy' } + }, + } + return nil, lenses + end) + notify('shutdown') + end; + } +end function tests.basic_formatting() skeleton { diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 3ee293db66..530d414334 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -2833,6 +2833,85 @@ describe('LSP', function() end } end) + + it('releases buffer refresh lock', function() + local client + local expected_handlers = { + {NIL, {}, {method="shutdown", client_id=1}}; + {NIL, {}, {method="start", client_id=1}}; + } + test_rpc_server { + test_name = 'codelens_refresh_lock', + on_init = function(client_) + client = client_ + end, + on_setup = function() + exec_lua([=[ + local bufnr = vim.api.nvim_get_current_buf() + vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {'One line'}) + vim.lsp.buf_attach_client(bufnr, TEST_RPC_CLIENT_ID) + + CALLED = false + RESPONSE = nil + local on_codelens = vim.lsp.codelens.on_codelens + vim.lsp.codelens.on_codelens = function (err, result, ...) + CALLED = true + RESPONSE = { err = err, result = result } + return on_codelens(err, result, ...) + end + ]=]) + end, + on_exit = function(code, signal) + eq(0, code, "exit code", fake_lsp_logfile) + eq(0, signal, "exit signal", fake_lsp_logfile) + end, + on_handler = function(err, result, ctx) + eq(table.remove(expected_handlers), {err, result, ctx}) + if ctx.method == 'start' then + -- 1. first codelens request errors + local response = exec_lua([=[ + CALLED = false + vim.lsp.codelens.refresh() + vim.wait(100, function () return CALLED end) + return RESPONSE + ]=]) + eq( { err = { code = -32002, message = "ServerNotInitialized" } }, response) + + -- 2. second codelens request runs + response = exec_lua([=[ + CALLED = false + local cmd_called = nil + vim.lsp.commands["Dummy"] = function (command) + cmd_called = command + end + vim.lsp.codelens.refresh() + vim.wait(100, function () return CALLED end) + vim.lsp.codelens.run() + vim.wait(100, function () return cmd_called end) + return cmd_called + ]=]) + eq( { command = "Dummy", title = "Lens1" }, response) + + -- 3. third codelens request runs + response = exec_lua([=[ + CALLED = false + local cmd_called = nil + vim.lsp.commands["Dummy"] = function (command) + cmd_called = command + end + vim.lsp.codelens.refresh() + vim.wait(100, function () return CALLED end) + vim.lsp.codelens.run() + vim.wait(100, function () return cmd_called end) + return cmd_called + ]=]) + eq( { command = "Dummy", title = "Lens2" }, response) + elseif ctx.method == 'shutdown' then + client.stop() + end + end + } + end) end) describe("vim.lsp.buf.format", function() |