diff options
author | Mathias Fussenegger <f.mathias@zignar.net> | 2022-08-23 21:05:46 +0200 |
---|---|---|
committer | Mathias Fussenegger <f.mathias@zignar.net> | 2022-08-28 14:07:53 +0200 |
commit | f9641d1ac6bae58a42572ce3bfa34d62d5f22619 (patch) | |
tree | 93129107e293d7f885487b6123e4f4cb2429cc29 /runtime/lua/vim/lsp/rpc.lua | |
parent | 88c32b5eba9fa7072bb4a76a8dbb73c6603165be (diff) | |
download | rneovim-f9641d1ac6bae58a42572ce3bfa34d62d5f22619.tar.gz rneovim-f9641d1ac6bae58a42572ce3bfa34d62d5f22619.tar.bz2 rneovim-f9641d1ac6bae58a42572ce3bfa34d62d5f22619.zip |
refactor(lsp): factor out read_loop function
Diffstat (limited to 'runtime/lua/vim/lsp/rpc.lua')
-rw-r--r-- | runtime/lua/vim/lsp/rpc.lua | 57 |
1 files changed, 32 insertions, 25 deletions
diff --git a/runtime/lua/vim/lsp/rpc.lua b/runtime/lua/vim/lsp/rpc.lua index 0926912066..f96321c845 100644 --- a/runtime/lua/vim/lsp/rpc.lua +++ b/runtime/lua/vim/lsp/rpc.lua @@ -241,6 +241,35 @@ function default_dispatchers.on_error(code, err) local _ = log.error() and log.error('client_error:', client_errors[code], err) end +---@private +local function create_read_loop(handle_body, on_no_chunk, on_error) + local parse_chunk = coroutine.wrap(request_parser_loop) + parse_chunk() + return function(err, chunk) + if err then + on_error(err) + return + end + + if not chunk then + if on_no_chunk then + on_no_chunk() + end + return + end + + while true do + local headers, body = parse_chunk(chunk) + if headers then + handle_body(body) + chunk = '' + else + break + end + end + end +end + --- Starts an LSP server process and create an LSP RPC client object to --- interact with it. Communication with the server is currently limited to stdio. --- @@ -592,31 +621,9 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params) local request_parser = coroutine.wrap(request_parser_loop) request_parser() - stdout:read_start(function(err, chunk) - if err then - -- TODO better handling. Can these be intermittent errors? - on_error(client_errors.READ_ERROR, err) - return - end - -- This should signal that we are done reading from the client. - if not chunk then - return - end - -- Flush anything in the parser by looping until we don't get a result - -- anymore. - while true do - local headers, body = request_parser(chunk) - -- If we successfully parsed, then handle the response. - if headers then - handle_body(body) - -- Set chunk to empty so that we can call request_parser to get - -- anything existing in the parser to flush. - chunk = '' - else - break - end - end - end) + stdout:read_start(create_read_loop(handle_body, nil, function(err) + on_error(client_errors.READ_ERROR, err) + end)) return { pid = pid, |