Files
clice/tests/fixtures/client.py
2025-08-10 22:31:00 +08:00

81 lines
2.4 KiB
Python

import asyncio
from pathlib import Path
from .transport import LSPTransport
class OpeningFile:
def __init__(self, content: str):
self.version = 0
self.content = content
class LSPClient(LSPTransport):
def __init__(self, commands, mode="stdio", host="127.0.0.1", port=2087):
super().__init__(commands, mode, host, port)
self.workspace = ""
self.opening_files: dict[Path, OpeningFile] = {}
async def initialize(self, workspace: str):
self.workspace = workspace
params = {
"clientInfo": {"name": "clice tester", "version": "0.0.1", },
"capabilities": {},
"workspaceFolders": [{"uri": Path(workspace).as_uri(), "name": "test"}],
}
return await self.send_request("initialize", params)
async def exit(self):
await self.send_notification("exit")
await self.stop()
def get_abs_path(self, relative_path: str):
return Path(self.workspace, relative_path)
def get_file(self, relative_path: str):
path = self.get_abs_path(relative_path)
return self.opening_files[path]
async def did_open(self, relative_path: str):
path = self.get_abs_path(relative_path)
content = ""
with open(path, encoding="utf-8") as file:
content = file.read()
if path in self.opening_files:
raise RuntimeError(f"Cannot open same file multiple times: {path}")
self.opening_files[path] = OpeningFile(content)
params = {
"textDocument": {
"uri": path.as_uri(),
"languageId": "cpp",
"version": 0,
"text": content,
}
}
await self.send_notification("textDocument/didOpen", params)
async def did_change(self, relative_path: str, content: str):
path = self.get_abs_path(relative_path)
if path not in self.opening_files:
raise RuntimeError(f"Cannot change closed file: {path}")
file = self.opening_files[path]
file.version += 1
file.content = content
params = {
"textDocument": {
"uri": path.as_uri(),
"version": file.version
},
"contentChanges": [
{"text": content, }
]
}
await self.send_notification("textDocument/didChange", params)