from logging import INFO, basicConfig, getLogger from pathlib import Path from lsprotocol.types import ( TEXT_DOCUMENT_DOCUMENT_SYMBOL, CompletionItem, Diagnostic, DiagnosticSeverity, DocumentSymbol, DocumentSymbolParams, Position, Range, ) from pygls.server import LanguageServer from parsimonious import Grammar, IncompleteParseError from .cache import Cache from .parsing.tokenize import Locator, SkillVisitor URI = str basicConfig(filename="skillls.log", level=INFO) cache: Cache[str, CompletionItem] = Cache() logger = getLogger(__name__) server = LanguageServer("skillls", "v0.1") def parse(content: str): path = Path(__file__).parent / "grammar.peg" grammar = Grammar(path.read_text()) locator = Locator(content) tree = grammar.parse(content) iv = SkillVisitor(locator) output = iv.visit(tree) return output @server.feature(TEXT_DOCUMENT_DOCUMENT_SYMBOL) def document_symbols(params: DocumentSymbolParams) -> list[DocumentSymbol]: logger.warning("requested document symbols for %s", params.text_document.uri) doc = server.workspace.get_text_document(params.text_document.uri) try: logger.warning(parse(doc.source)) except IncompleteParseError as e: server.publish_diagnostics( params.text_document.uri, [ Diagnostic( Range( Position(e.line() - 1, e.column() - 1), Position(len(doc.lines), 0), ), str(e), severity=DiagnosticSeverity.Error, ) ], ) return [] def main(): server.start_io() if __name__ == "__main__": file = Path(__file__).parent.parent / "examples" / "example.il" parse(file.read_text())