Replies: 5 comments 5 replies
-
Yes... compared to the rest of With that out of the way, the following code will spin up and instance of import asyncio
from lsprotocol import types
from pygls.lsp.client import BaseLanguageClient
async def main():
client = BaseLanguageClient("example-client", "v1")
# Start the server running in a subprocess
await client.start_io("ruff-lsp")
# Start the LSP session
response = await client.initialize_async(
types.InitializeParams(
capabilities=types.ClientCapabilities(),
root_uri="file:///path/to/project",
)
)
print(f"Got response: {response}")
# Tell ruff-lsp to get ready to exit and it acknowledge the request
await client.shutdown_async(None)
# Tell ruff-lsp to actually exit
client.exit(None)
# Close down the client and server subprocess
await client.stop()
asyncio.run(main()) (assuming you have This does however, leave you however in a bit of a "draw the rest of the owl" situation! 😅 At the very least you're probably going to want to look into the notifications From there you can find examples of some specific LSP methods in this test folder and I did put together a proof of concept language client built on Textual, which you might find useful Also if you have any follow up questions feel free to ask! :) |
Beta Was this translation helpful? Give feedback.
-
@alcarney Thank you for your wonderful base example on using pygls clients. But basedpyright and pyright haven't been so kind to me import asyncio
from lsprotocol import types
from pygls.lsp.client import BaseLanguageClient
class LanguageClient(BaseLanguageClient):
async def server_exit(self, server: asyncio.subprocess.Process):
"""Called when the server process exits."""
# 0: all good
# -15: terminated
print(server.returncode)
if server.returncode not in {0, -15}:
print(f"Server process exited with code: {server.returncode}")
if server.stderr is not None:
stderr = await server.stderr.read()
print(f"Stderr:\n{stderr.decode('utf8')}")
raise SystemExit(server.returncode)
async def main():
client = LanguageClient("example-client", "v1")
await client.start_io("basedpyright-langserver", "--stdio")
await client.initialize_async(
types.InitializeParams(
capabilities=types.ClientCapabilities(),
root_uri="file:///home/axis/p/axedit",
)
)
response = await client.text_document_completion_async(
types.CompletionParams(
types.TextDocumentIdentifier("file:///home/axis/p/axedit/axedit/cli.py"),
types.Position(0, 1),
)
)
print([item.label for item in response.items])
await client.shutdown_async(None)
client.exit(None)
await client.stop()
asyncio.run(main()) The output Ignoring notification for unknown method "window/logMessage"
Ignoring notification for unknown method "window/logMessage"
Ignoring notification for unknown method "window/logMessage" I'm not sure where I'm going wrong, but switching it out with |
Beta Was this translation helpful? Give feedback.
-
Related, I found an issue edit: figured it out, i think it was: client.initialized(types.InitializedParams()) |
Beta Was this translation helpful? Give feedback.
-
Trying it with some updated code now, it still only gives me empty results import asyncio
from lsprotocol import types
from pygls.lsp.client import BaseLanguageClient
class LanguageClient(BaseLanguageClient):
async def server_exit(self, server: asyncio.subprocess.Process):
"""Called when the server process exits."""
# 0: all good
# -15: terminated
print(server.returncode)
if server.returncode not in {0, -15}:
print(f"Server process exited with code: {server.returncode}")
if server.stderr is not None:
stderr = await server.stderr.read()
print(f"Stderr:\n{stderr.decode('utf8')}")
raise SystemExit(server.returncode)
async def main():
client = LanguageClient("example-client", "v1")
await client.start_io("basedpyright-langserver", "--stdio")
# await client.start_io("pyright-langserver", "--stdio")
await client.initialize_async(
types.InitializeParams(
capabilities=types.ClientCapabilities(),
root_uri="file:///home/axis/p/axedit",
)
)
client.initialized(types.InitializedParams())
response = await client.text_document_completion_async(
types.CompletionParams(
types.TextDocumentIdentifier("file:///home/axis/p/axedit/axedit/cli.py"),
types.Position(0, 2),
)
)
print(f"AUTOCOMPLETE RESULTS = {response}")
response = await client.text_document_semantic_tokens_full_async(
types.SemanticTokensParams(
types.TextDocumentIdentifier("file:///home/axis/p/axedit/axedit/cli.py")
)
)
print(f"SEMANTIC TOKENS RESULT = {response}")
await client.shutdown_async(None)
client.exit(None)
await client.stop()
asyncio.run(main())
|
Beta Was this translation helpful? Give feedback.
-
@alcarney Okay, so I got the semantic highlighting working! response = await client.text_document_semantic_tokens_full_async(
types.SemanticTokensParams(types.TextDocumentIdentifier(file_path))
)
print(f"SEMANTIC TOKENS RESULT = {response}")
# print(list(itertools.batched(response.data, n=5))) What does the tokens result data actually mean? SEMANTIC TOKENS RESULT = SemanticTokens(data=[0, 7, 3, 7, 0, 0, 0, 3, 7, 0, 1, 7, 6, 7, 0, 0, 10, 1, 7, 0, 0, 0, 1, 7, 0, 1, 5, 7, 7, 0, 0, 15, 4, 0, 0, 0, 0, 4, 0, 0, 2, 7, 11, 7, 0, 0, 0, 11, 7, 0, 1, 5, 4, 7, 0, 0, 5, 7, 7, 0, 0, 15, 7, 0, 0, 0, 0, 7, 0, 0, 2, 0, 4, 8, 0, 0, 20, 3, 3, 48, 0, 4, 3, 7, 0, 0, 4, 4, 8, 0, 0, 16, 3, 7, 0, 0, 4, 4, 8, 0, 2, 0, 8, 8, 0, 0, 11, 4, 0, 0, 0, 5, 4, 8, 0, 0, 6, 6, 8, 0, 1, 0, 16, 8, 0, 2, 0, 11, 8, 0, 0, 14, 16, 8, 0, 0, 17, 3, 4, 0, 0, 4, 8, 8, 0, 1, 0, 6, 8, 0, 0, 9, 10, 3, 48, 0, 26, 11, 8, 0, 2, 0, 1, 8, 0, 0, 4, 11, 7, 0, 0, 12, 6, 0, 0, 0, 7, 11, 7, 0, 0, 12, 8, 0, 0, 0, 9, 6, 8, 0, 1, 5, 4, 3, 48, 0, 5, 4, 8, 0, 0, 15, 1, 8, 0, 1, 4, 4, 8, 0, 0, 7, 1, 8, 0, 0, 2, 4, 4, 0, 1, 4, 4, 8, 0, 0, 7, 1, 8, 0, 0, 2, 5, 4, 0, 0, 6, 4, 8, 0, 3, 0, 10, 8, 0, 0, 12, 4, 0, 48, 0, 5, 3, 0, 48, 0, 5, 3, 0, 48, 3, 4, 13, 3, 1, 0, 0, 13, 3, 0, 0, 14, 4, 1, 1, 0, 6, 11, 7, 0, 0, 12, 4, 0, 0, 0, 9, 1, 7, 0, 0, 2, 8, 0, 0, 0, 9, 11, 7, 0, 0, 12, 4, 0, 0, 1, 4, 6, 8, 0, 0, 9, 4, 1, 0, 0, 5, 4, 4, 0, 2, 4, 16, 8, 0, 1, 4, 10, 8, 0, 2, 15, 16, 8, 0, 1, 19, 6, 8, 0, 0, 7, 16, 4, 0, 1, 19, 6, 8, 0, 0, 7, 4, 8, 0, 0, 5, 4, 8, 0, 1, 20, 10, 8, 0, 0, 11, 6, 8, 0, 0, 7, 4, 8, 0, 0, 5, 10, 8, 0, 0, 14, 10, 8, 0, 1, 22, 6, 8, 0, 0, 7, 4, 8, 0, 1, 16, 16, 8, 0, 1, 13, 6, 8, 0, 0, 7, 17, 4, 0, 1, 12, 16, 8, 0, 1, 17, 6, 8, 0, 0, 7, 11, 4, 0, 3, 8, 10, 8, 0, 0, 11, 6, 4, 0, 0, 7, 6, 8, 0, 0, 7, 4, 8, 0, 3, 4, 10, 3, 1, 0, 0, 10, 3, 0, 0, 11, 9, 1, 1, 1, 4, 9, 1, 0, 0, 12, 9, 1, 0, 1, 11, 5, 0, 48, 0, 6, 3, 0, 48, 0, 4, 9, 1, 0, 0, 10, 1, 8, 0, 0, 4, 1, 8, 0, 0, 16, 1, 8, 0, 3, 4, 11, 3, 1, 0, 0, 11, 3, 0, 0, 12, 9, 1, 1, 1, 4, 3, 8, 0, 0, 6, 10, 3, 0, 0, 11, 9, 1, 0, 1, 4, 5, 3, 48, 0, 19, 3, 8, 0, 0, 9, 3, 8, 0, 0, 9, 3, 8, 0, 0, 11, 3, 1, 0, 3, 0, 10, 8, 0, 1, 0, 8, 8, 0, 1, 0, 9, 8, 0, 1, 0, 7, 8, 0, 1, 0, 7, 8, 0, 1, 0, 10, 8, 0, 1, 0, 8, 8, 0, 1, 0, 8, 8, 0, 1, 0, 3, 8, 0, 1, 0, 14, 8, 0, 1, 0, 7, 8, 0, 1, 0, 7, 8, 0, 1, 0, 5, 8, 0, 1, 0, 4, 8, 0, 1, 0, 8, 8, 0, 1, 0, 10, 8, 0, 2, 0, 6, 8, 8, 1, 4, 8, 8, 0, 15, 4, 7, 8, 0, 1, 4, 14, 8, 0, 1, 4, 7, 8, 0, 1, 4, 7, 8, 0, 1, 4, 4, 8, 0, 1, 4, 3, 8, 0, 2, 0, 6, 8, 8, 1, 4, 5, 8, 0, 0, 7, 5, 8, 0, 0, 9, 6, 8, 8, 0, 7, 5, 4, 0, 1, 8, 2, 8, 0, 0, 6, 5, 8, 0, 1, 8, 6, 8, 8, 0, 7, 2, 8, 0, 0, 6, 5, 8, 0, 2, 16, 3, 7, 0, 0, 4, 4, 8, 0, 1, 4, 5, 3, 48, 0, 8, 4, 8, 0, 0, 5, 4, 8, 0, 0, 9, 4, 8, 0, 0, 8, 13, 3, 0, 0, 14, 4, 8, 0, 0, 8, 3, 1, 0, 1, 4, 4, 3, 48, 1, 17, 3, 7, 0, 0, 4, 4, 8, 0, 1, 4, 5, 3, 48, 0, 6, 4, 8, 0, 0, 5, 9, 8, 0, 1, 4, 4, 3, 48, 1, 15, 3, 7, 0, 1, 4, 4, 0, 48, 0, 5, 13, 3, 0, 0, 14, 4, 8, 0, 1, 4, 5, 3, 48, 0, 7, 10, 8, 0, 0, 11, 6, 4, 0, 0, 10, 3, 1, 0, 1, 4, 4, 3, 48, 2, 0, 7, 8, 0, 0, 10, 7, 0, 0, 1, 0, 5, 8, 0, 0, 8, 13, 3, 0, 0, 14, 4, 8, 0, 1, 0, 9, 8, 0, 0, 12, 4, 3, 48, 0, 5, 5, 8, 0, 1, 4, 12, 8, 0, 0, 14, 4, 8, 0, 0, 8, 9, 0, 48, 0, 10, 4, 8, 0, 0, 5, 6, 4, 0, 1, 7, 12, 8, 0, 0, 16, 9, 8, 0, 0, 10, 10, 8, 0, 1, 8, 9, 8, 0, 0, 12, 9, 8, 0, 0, 10, 4, 8, 0, 1, 11, 9, 8, 0, 0, 10, 4, 8, 0, 1, 12, 9, 8, 0, 0, 12, 10, 8, 0, 0, 11, 3, 4, 0, 0, 4, 12, 8, 0, 2, 8, 5, 8, 0, 0, 8, 6, 8, 8, 0, 7, 3, 4, 0, 0, 4, 9, 8, 0, 1, 8, 11, 3, 0, 0, 12, 5, 8, 0, 2, 12, 9, 8, 0, 0, 12, 4, 3, 48, 0, 5, 5, 8, 0, 1, 15, 13, 0, 48, 2, 4, 5, 3, 48, 0, 6, 4, 8, 0, 0, 6, 3, 1, 0], result_id='1722108597816') |
Beta Was this translation helpful? Give feedback.
-
I want to eventually make simple multipurpose client that makes it easy to interface with Language Servers for a project of mine but I have very little knowledge of how to work with LSP's. Having looked at many alternatives,
pygls
seems like the best option available to get started but the Clients have very few examples and its not very clear how to get started with them. A basic example for interfacing withruff-lsp
(already installed locally) would be a major help. I saw this discussion but it didn't make much sense to me. Thank you for any time and effort in helping me out!!Beta Was this translation helpful? Give feedback.
All reactions