Unable to register custom command
gsabran opened this issue · 2 comments
gsabran commented
I'm trying to register a custom command, following the documentation as well as I can. But when the server receives this command it fails. What should I do differently?
import logging
from pygls.server import LanguageServer as ls
logging.basicConfig(filename='pygls.log', filemode='w', level=logging.DEBUG)
server = ls('example-server', 'v0.1')
@server.command('saySomething')
def saySomething(ls, *args):
"""Returns completion items."""
return "hello"
server.start_io()
The error log is:
ERROR:pygls.protocol.json_rpc:Failed to handle request 3 saySomething Object(lastToken=None, params=None)
Traceback (most recent call last):
File ".../pygls/protocol/json_rpc.py", line 218, in _get_handler
return self.fm.builtin_features[feature_name]
~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
KeyError: 'saySomething'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File ".../pygls/protocol/json_rpc.py", line 221, in _get_handler
return self.fm.features[feature_name]
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^
KeyError: 'saySomething'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File ".../pygls/protocol/json_rpc.py", line 260, in _handle_request
handler = self._get_handler(method_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File ".../pygls/protocol/json_rpc.py", line 223, in _get_handler
raise JsonRpcMethodNotFound.of(feature_name)
pygls.exceptions.JsonRpcMethodNotFound: Method Not Found: saySomething
INFO:pygls.protocol.json_rpc:Sending data: {"error": {"code": -32601, "message": "Method Not Found: saySomething"}, "jsonrpc": "2.0", "id": 3}
Thanks a lot for the support.
alcarney commented
Your server code looks fine, the issue is probably with how the client is interacting with it.
Commands in LSP cannot be called directly, instead the client needs to send a workspace/executeCommand
request, specifying the name of the command it wishes to call.
For example
import asyncio
import sys
from lsprotocol import types
from pygls.lsp.client import BaseLanguageClient
async def main():
client = BaseLanguageClient("client", "v1")
await client.start_io(sys.executable, "test.py")
response = await client.initialize_async(
types.InitializeParams(capabilities=types.ClientCapabilities())
)
available_commands = response.capabilities.execute_command_provider.commands
print(f"Available commands: {available_commands}")
command_name = available_commands[0]
print(f"Calling command: {command_name!r}")
response = await client.workspace_execute_command_async(
types.ExecuteCommandParams(
command=command_name, arguments=[]
)
)
print(f"Result: {response!r}")
await client.shutdown_async(None)
client.exit(None)
await client.stop()
asyncio.run(main())
Saving your code to a file called test.py
I was able to use the code above to get the following result
$ python client.py
Available commands: ['saySomething']
Calling command: 'saySomething'
Result: 'hello'
Hope that helps! :)
gsabran commented
You are right, thanks a lot!