While using textadept-lsp with metals, an LSP server for Scala, I was unable to get it to communicate with Textadept.
On viewing the metals logfile, I saw the following error:
WARNING: Issue found in NotificationMessage: Message could not be parsed.
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 51 path $.params
which occured when textadept sent the initialized message.
Indeed, looking at the RPC log in textadept, I can see that it is sending an array for the params field when it is empty (whereas when it is not empty it is an object):
The lsp plugin is creating an empty lua table for the params in this case:
function Server:notify(method, params)
local message = {jsonrpc = '2.0', method = method, params = params or {}}
but because Lua has the same datastructure for objects and arrays, dkjson defaults to converting the table to an array unless it has a metatable attribute __jsontype to say otherwise:
`<metatable>.__jsontype`
------------------------
`__jsontype` can be either `"array"` or `"object"`. This value is only
checked for empty tables. (The default for empty tables is `"array"`).
A simple way to create a table with such a metatable field is to use json.decode('{}').
The proposed change here does just that. The result is that we send this to the server:
While using
textadept-lsp
with metals, an LSP server for Scala, I was unable to get it to communicate with Textadept.On viewing the metals logfile, I saw the following error:
which occured when textadept sent the
initialized
message.Indeed, looking at the RPC log in textadept, I can see that it is sending an array for the params field when it is empty (whereas when it is not empty it is an object):
The lsp plugin is creating an empty lua table for the params in this case:
but because Lua has the same datastructure for objects and arrays,
dkjson
defaults to converting the table to an array unless it has a metatable attribute__jsontype
to say otherwise:A simple way to create a table with such a metatable field is to use
json.decode('{}')
.The proposed change here does just that. The result is that we send this to the server:
which is parsed correctly by metals and after which it then works perfectly.