diff options
author | Ilia Choly <ilia.choly@gmail.com> | 2024-05-23 09:17:53 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-23 15:17:53 +0200 |
commit | af200c10cf9d117a14ebf9f2e9c666721a1090d6 (patch) | |
tree | 96f4e94ed24dff6a0ddea56d2c19bf96731470cd | |
parent | 2908f71dc9e9591f97e0f9d70dbc8d8b18f9e475 (diff) | |
download | rneovim-af200c10cf9d117a14ebf9f2e9c666721a1090d6.tar.gz rneovim-af200c10cf9d117a14ebf9f2e9c666721a1090d6.tar.bz2 rneovim-af200c10cf9d117a14ebf9f2e9c666721a1090d6.zip |
fix(lsp): check if buffer was detached in on_init callback (#28914)
Co-authored-by: Jongwook Choi <wookayin@gmail.com>
-rw-r--r-- | runtime/lua/vim/lsp/client.lua | 5 | ||||
-rw-r--r-- | test/functional/plugin/lsp/inlay_hint_spec.lua | 12 | ||||
-rw-r--r-- | test/functional/plugin/lsp/semantic_tokens_spec.lua | 34 | ||||
-rw-r--r-- | test/functional/plugin/lsp/testutil.lua | 3 | ||||
-rw-r--r-- | test/functional/plugin/lsp_spec.lua | 57 |
5 files changed, 71 insertions, 40 deletions
diff --git a/runtime/lua/vim/lsp/client.lua b/runtime/lua/vim/lsp/client.lua index 8fb5879e9b..4beb7fefda 100644 --- a/runtime/lua/vim/lsp/client.lua +++ b/runtime/lua/vim/lsp/client.lua @@ -612,7 +612,10 @@ function Client:initialize() self:_run_callbacks(self._on_init_cbs, lsp.client_errors.ON_INIT_CALLBACK_ERROR, self, result) for buf in pairs(reattach_bufs) do - self:_on_attach(buf) + -- The buffer may have been detached in the on_init callback. + if self.attached_buffers[buf] then + self:_on_attach(buf) + end end log.info( diff --git a/test/functional/plugin/lsp/inlay_hint_spec.lua b/test/functional/plugin/lsp/inlay_hint_spec.lua index 3d0fcc31ff..d3b5ae0e4e 100644 --- a/test/functional/plugin/lsp/inlay_hint_spec.lua +++ b/test/functional/plugin/lsp/inlay_hint_spec.lua @@ -70,8 +70,8 @@ before_each(function() inlayHintProvider = true, }, handlers = { - ['textDocument/inlayHint'] = function() - return vim.json.decode(response) + ['textDocument/inlayHint'] = function(_, _, callback) + callback(nil, vim.json.decode(response)) end, } }) @@ -106,8 +106,8 @@ describe('vim.lsp.inlay_hint', function() inlayHintProvider = true, }, handlers = { - ['textDocument/inlayHint'] = function() - return {} + ['textDocument/inlayHint'] = function(_, _, callback) + callback(nil, {}) end, } }) @@ -206,8 +206,8 @@ describe('vim.lsp.inlay_hint', function() inlayHintProvider = true, }, handlers = { - ['textDocument/inlayHint'] = function() - return { expected2 } + ['textDocument/inlayHint'] = function(_, _, callback) + callback(nil, { expected2 }) end, } }) diff --git a/test/functional/plugin/lsp/semantic_tokens_spec.lua b/test/functional/plugin/lsp/semantic_tokens_spec.lua index 60f02b0521..7908c5d2e7 100644 --- a/test/functional/plugin/lsp/semantic_tokens_spec.lua +++ b/test/functional/plugin/lsp/semantic_tokens_spec.lua @@ -95,11 +95,11 @@ describe('semantic token highlighting', function() }, }, handlers = { - ['textDocument/semanticTokens/full'] = function() - return vim.fn.json_decode(response) + ['textDocument/semanticTokens/full'] = function(_, _, callback) + callback(nil, vim.fn.json_decode(response)) end, - ['textDocument/semanticTokens/full/delta'] = function() - return vim.fn.json_decode(edit_response) + ['textDocument/semanticTokens/full/delta'] = function(_, _, callback) + callback(nil, vim.fn.json_decode(edit_response)) end, } }) @@ -560,11 +560,11 @@ describe('semantic token highlighting', function() }, }, handlers = { - ['textDocument/semanticTokens/full'] = function() - return nil + ['textDocument/semanticTokens/full'] = function(_, _, callback) + callback(nil, nil) end, ['textDocument/semanticTokens/full/delta'] = function() - return nil + callback(nil, nil) end, } }) @@ -608,11 +608,11 @@ describe('semantic token highlighting', function() }, }, handlers = { - ['textDocument/semanticTokens/full'] = function() - return vim.fn.json_decode(response) + ['textDocument/semanticTokens/full'] = function(_, _, callback) + callback(nil, vim.fn.json_decode(response)) end, - ['textDocument/semanticTokens/full/delta'] = function() - return vim.fn.json_decode(edit_response) + ['textDocument/semanticTokens/full/delta'] = function(_, _, callback) + callback(nil, vim.fn.json_decode(edit_response)) end, } }) @@ -1075,8 +1075,8 @@ b = "as"]], }, }, handlers = { - ['textDocument/semanticTokens/full'] = function() - return vim.fn.json_decode(resp) + ['textDocument/semanticTokens/full'] = function(_, _, callback) + callback(nil, vim.fn.json_decode(resp)) end, } }) @@ -1461,11 +1461,11 @@ int main() }, }, handlers = { - ['textDocument/semanticTokens/full'] = function() - return vim.fn.json_decode(resp1) + ['textDocument/semanticTokens/full'] = function(_, _, callback) + callback(nil, vim.fn.json_decode(resp1)) end, - ['textDocument/semanticTokens/full/delta'] = function() - return vim.fn.json_decode(resp2) + ['textDocument/semanticTokens/full/delta'] = function(_, _, callback) + callback(nil, vim.fn.json_decode(resp2)) end, } }) diff --git a/test/functional/plugin/lsp/testutil.lua b/test/functional/plugin/lsp/testutil.lua index 4d14752f2a..3430a1e1a3 100644 --- a/test/functional/plugin/lsp/testutil.lua +++ b/test/functional/plugin/lsp/testutil.lua @@ -39,8 +39,7 @@ M.create_server_definition = [[ }) local handler = handlers[method] if handler then - local response, err = handler(method, params) - callback(err, response) + handler(method, params, callback) elseif method == 'initialize' then callback(nil, { capabilities = opts.capabilities or {} diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua index 8358a1b9ec..c95a96baca 100644 --- a/test/functional/plugin/lsp_spec.lua +++ b/test/functional/plugin/lsp_spec.lua @@ -501,6 +501,35 @@ describe('LSP', function() eq(true, result.detach_called) end) + it('should not re-attach buffer if it was deleted in on_init #28575', function() + clear() + exec_lua(create_server_definition) + exec_lua([[ + local server = _create_server({ + handlers = { + initialize = function(method, params, callback) + vim.schedule(function() + callback(nil, { capabilities = {} }) + end) + end + } + }) + local bufnr = vim.api.nvim_create_buf(false, true) + local on_init_called = false + local client_id = vim.lsp.start({ + name = 'detach-dummy', + cmd = server.cmd, + on_init = function() + vim.api.nvim_buf_delete(bufnr, {}) + on_init_called = true + end + }) + vim.lsp.buf_attach_client(bufnr, client_id) + local ok = vim.wait(1000, function() return on_init_called end) + assert(ok, "on_init was not called") + ]]) + end) + it('client should return settings via workspace/configuration handler', function() local expected_handlers = { { NIL, {}, { method = 'shutdown', client_id = 1 } }, @@ -670,7 +699,7 @@ describe('LSP', function() } }, handlers = { - ['textDocument/willSaveWaitUntil'] = function() + ['textDocument/willSaveWaitUntil'] = function(_, _, callback) local text_edit = { range = { start = { line = 0, character = 0 }, @@ -678,7 +707,7 @@ describe('LSP', function() }, newText = 'Hello' } - return { text_edit, } + callback(nil, { text_edit, }) end }, }) @@ -4144,8 +4173,8 @@ describe('LSP', function() } }, handlers = { - ["textDocument/codeAction"] = function() - return { + ["textDocument/codeAction"] = function(_, _, callback) + callback(nil, { { title = "Code Action 1", command = { @@ -4153,10 +4182,10 @@ describe('LSP', function() command = "command:1", } } - } + }) end, - ["codeAction/resolve"] = function() - return nil, "resolve failed" + ["codeAction/resolve"] = function(_, _, callback) + callback("resolve failed", nil) end, } }) @@ -4344,7 +4373,7 @@ describe('LSP', function() }, }, handlers = { - ["textDocument/codeLens"] = function(method, params) + ["textDocument/codeLens"] = function(method, params, callback) local lenses = { { range = { @@ -4357,7 +4386,7 @@ describe('LSP', function() }, }, } - return lenses + callback(nil, lenses) end, } }) @@ -4665,13 +4694,13 @@ describe('LSP', function() }, handlers = { ---@return lsp.Location[] - ['textDocument/definition'] = function() - return { _G.mock_locations[1] } + ['textDocument/definition'] = function(_, _, callback) + callback(nil, { _G.mock_locations[1] }) end, ---@return lsp.WorkspaceSymbol[] - ['workspace/symbol'] = function(_, request) + ['workspace/symbol'] = function(_, request, callback) assert(request.query == 'foobar') - return { + callback(nil, { { name = 'foobar', kind = 13, ---@type lsp.SymbolKind @@ -4682,7 +4711,7 @@ describe('LSP', function() kind = 12, ---@type lsp.SymbolKind location = _G.mock_locations[2], } - } + }) end, }, }) |