aboutsummaryrefslogtreecommitdiff
path: root/runtime/lua/vim/lsp/rpc.lua
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/lua/vim/lsp/rpc.lua')
-rw-r--r--runtime/lua/vim/lsp/rpc.lua87
1 files changed, 8 insertions, 79 deletions
diff --git a/runtime/lua/vim/lsp/rpc.lua b/runtime/lua/vim/lsp/rpc.lua
index 7f31bbdf75..d9a684a738 100644
--- a/runtime/lua/vim/lsp/rpc.lua
+++ b/runtime/lua/vim/lsp/rpc.lua
@@ -4,34 +4,6 @@ local log = require('vim.lsp.log')
local protocol = require('vim.lsp.protocol')
local validate, schedule, schedule_wrap = vim.validate, vim.schedule, vim.schedule_wrap
--- TODO replace with a better implementation.
----@private
---- Encodes to JSON.
----
----@param data (table) Data to encode
----@returns (string) Encoded object
-local function json_encode(data)
- local status, result = pcall(vim.fn.json_encode, data)
- if status then
- return result
- else
- return nil, result
- end
-end
----@private
---- Decodes from JSON.
----
----@param data (string) Data to decode
----@returns (table) Decoded JSON object
-local function json_decode(data)
- local status, result = pcall(vim.fn.json_decode, data)
- if status then
- return result
- else
- return nil, result
- end
-end
-
---@private
--- Checks whether a given path exists and is a directory.
---@param filename (string) path to check
@@ -41,36 +13,6 @@ local function is_dir(filename)
return stat and stat.type == 'directory' or false
end
-local NIL = vim.NIL
-
----@private
-local recursive_convert_NIL
-recursive_convert_NIL = function(v, tbl_processed)
- if v == NIL then
- return nil
- elseif not tbl_processed[v] and type(v) == 'table' then
- tbl_processed[v] = true
- local inside_list = vim.tbl_islist(v)
- return vim.tbl_map(function(x)
- if not inside_list or (inside_list and type(x) == "table") then
- return recursive_convert_NIL(x, tbl_processed)
- else
- return x
- end
- end, v)
- end
-
- return v
-end
-
----@private
---- Returns its argument, but converts `vim.NIL` to Lua `nil`.
----@param v (any) Argument
----@returns (any)
-local function convert_NIL(v)
- return recursive_convert_NIL(v, {})
-end
-
---@private
--- Merges current process env with the given env and returns the result as
--- a list of "k=v" strings.
@@ -389,16 +331,13 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params)
--- Encodes {payload} into a JSON-RPC message and sends it to the remote
--- process.
---
- ---@param payload (table) Converted into a JSON string, see |json_encode()|
+ ---@param payload table
---@returns true if the payload could be scheduled, false if the main event-loop is in the process of closing.
local function encode_and_send(payload)
local _ = log.debug() and log.debug("rpc.send", payload)
if handle == nil or handle:is_closing() then return false end
- -- TODO(ashkan) remove this once we have a Lua json_encode
- schedule(function()
- local encoded = assert(json_encode(payload))
- stdin:write(format_message_with_content_length(encoded))
- end)
+ local encoded = vim.json.encode(payload)
+ stdin:write(format_message_with_content_length(encoded))
return true
end
@@ -488,16 +427,15 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params)
---@private
local function handle_body(body)
- local decoded, err = json_decode(body)
- if not decoded then
- -- on_error(client_errors.INVALID_SERVER_JSON, err)
+ local ok, decoded = pcall(vim.json.decode, body, { luanil = { object = true } })
+ if not ok then
+ on_error(client_errors.INVALID_SERVER_JSON, decoded)
return
end
local _ = log.debug() and log.debug("rpc.receive", decoded)
if type(decoded.method) == 'string' and decoded.id then
- -- Server Request
- decoded.params = convert_NIL(decoded.params)
+ local err
-- Schedule here so that the users functions don't trigger an error and
-- we can still use the result.
schedule(function()
@@ -524,22 +462,16 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params)
end)
-- This works because we are expecting vim.NIL here
elseif decoded.id and (decoded.result ~= vim.NIL or decoded.error ~= vim.NIL) then
- -- Server Result
- decoded.error = convert_NIL(decoded.error)
- decoded.result = convert_NIL(decoded.result)
-- We sent a number, so we expect a number.
local result_id = tonumber(decoded.id)
- -- Do not surface RequestCancelled or ContentModified to users, it is RPC-internal.
+ -- Do not surface RequestCancelled to users, it is RPC-internal.
if decoded.error then
local mute_error = false
if decoded.error.code == protocol.ErrorCodes.RequestCancelled then
local _ = log.debug() and log.debug("Received cancellation ack", decoded)
mute_error = true
- elseif decoded.error.code == protocol.ErrorCodes.ContentModified then
- local _ = log.debug() and log.debug("Received content modified ack", decoded)
- mute_error = true
end
if mute_error then
@@ -574,7 +506,6 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params)
end
elseif type(decoded.method) == 'string' then
-- Notification
- decoded.params = convert_NIL(decoded.params)
try_call(client_errors.NOTIFICATION_HANDLER_ERROR,
dispatchers.notification, decoded.method, decoded.params)
else
@@ -582,8 +513,6 @@ local function start(cmd, cmd_args, dispatchers, extra_spawn_params)
on_error(client_errors.INVALID_SERVER_MESSAGE, decoded)
end
end
- -- TODO(ashkan) remove this once we have a Lua json_decode
- handle_body = schedule_wrap(handle_body)
local request_parser = coroutine.wrap(request_parser_loop)
request_parser()