fix(lsp): support false result in handlers (#20252)

Closes https://github.com/neovim/neovim/issues/20111
This commit is contained in:
Mathias Fußenegger 2022-09-20 09:28:23 +02:00 committed by GitHub
parent a0e6e767a6
commit 10196f1b46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 72 additions and 2 deletions

View File

@ -405,8 +405,7 @@ function Client:handle_body(body)
{ status = status, result = result, err = err } { status = status, result = result, err = err }
) )
if status then if status then
if not (result or err) then if result == nil and err == nil then
-- TODO this can be a problem if `null` is sent for result. needs vim.NIL
error( error(
string.format( string.format(
'method %q: either a result or an error must be sent to the server in response', 'method %q: either a result or an error must be sent to the server in response',

View File

@ -3292,4 +3292,75 @@ describe('LSP', function()
eq(result.method, "initialize") eq(result.method, "initialize")
end) end)
end) end)
describe('handlers', function()
it('handler can return false as response', function()
local result = exec_lua [[
local uv = vim.loop
local server = uv.new_tcp()
local messages = {}
local responses = {}
server:bind('127.0.0.1', 0)
server:listen(127, function(err)
assert(not err, err)
local socket = uv.new_tcp()
server:accept(socket)
socket:read_start(require('vim.lsp.rpc').create_read_loop(function(body)
local payload = vim.json.decode(body)
if payload.method then
table.insert(messages, payload.method)
if payload.method == 'initialize' then
local msg = vim.json.encode({
id = payload.id,
jsonrpc = '2.0',
result = {
capabilities = {}
},
})
socket:write(table.concat({'Content-Length: ', tostring(#msg), '\r\n\r\n', msg}))
elseif payload.method == 'initialized' then
local msg = vim.json.encode({
id = 10,
jsonrpc = '2.0',
method = 'dummy',
params = {},
})
socket:write(table.concat({'Content-Length: ', tostring(#msg), '\r\n\r\n', msg}))
end
else
table.insert(responses, payload)
socket:close()
end
end))
end)
local port = server:getsockname().port
local handler_called = false
vim.lsp.handlers['dummy'] = function(err, result)
handler_called = true
return false
end
local client_id = vim.lsp.start({ name = 'dummy', cmd = vim.lsp.rpc.connect('127.0.0.1', port) })
local client = vim.lsp.get_client_by_id(client_id)
vim.wait(1000, function() return #messages == 2 and handler_called and #responses == 1 end)
server:close()
server:shutdown()
return {
messages = messages,
handler_called = handler_called,
responses = responses }
]]
local expected = {
messages = { 'initialize', 'initialized' },
handler_called = true,
responses = {
{
id = 10,
jsonrpc = '2.0',
result = false
}
}
}
eq(expected, result)
end)
end)
end) end)