skill-ls/skillls/main.py

73 lines
1.8 KiB
Python

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())