From 47dbda97d2f40729733b1c0d1d13d914065af23c Mon Sep 17 00:00:00 2001 From: Mathias Fußenegger Date: Fri, 26 Apr 2024 09:57:59 +0200 Subject: fix(lsp): buffer messages until connected to server (#28507) `handle:write(msg)` can fail if the socket is not yet connected to the server. Should address https://github.com/neovim/neovim/pull/28398#issuecomment-2078152491 --- runtime/lua/vim/lsp/rpc.lua | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) (limited to 'runtime/lua/vim/lsp') diff --git a/runtime/lua/vim/lsp/rpc.lua b/runtime/lua/vim/lsp/rpc.lua index 6748b32ec0..d73e46edfb 100644 --- a/runtime/lua/vim/lsp/rpc.lua +++ b/runtime/lua/vim/lsp/rpc.lua @@ -645,9 +645,23 @@ function M.connect(host_or_path, port) or assert(uv.new_tcp(), 'Could not create new TCP socket') ) local closing = false + -- Connect returns a PublicClient synchronously so the caller + -- can immediately send messages before the connection is established + -- -> Need to buffer them until that happens + local connected = false + -- size should be enough because the client can't really do anything until initialization is done + -- which required a response from the server - implying the connection got established + local msgbuf = vim.ringbuf(10) local transport = { write = function(msg) - handle:write(msg) + if connected then + local _, err = handle:write(msg) + if err and not closing then + log.error('Error on handle:write: %q', err) + end + else + msgbuf:push(msg) + end end, is_closing = function() return closing @@ -679,6 +693,10 @@ function M.connect(host_or_path, port) handle:read_start(M.create_read_loop(handle_body, transport.terminate, function(read_err) client:on_error(M.client_errors.READ_ERROR, read_err) end)) + connected = true + for msg in msgbuf do + handle:write(msg) + end end if port == nil then handle:connect(host_or_path, on_connect) -- cgit