add more complex example

This commit is contained in:
AcerecA 2025-01-20 15:10:20 +01:00
parent a9ce78c1a3
commit 7b4f3b7119
2 changed files with 100 additions and 21 deletions

View File

@ -5,11 +5,11 @@ example2 = example
( (
(let (some vars (default 0)) (let (some vars (default 0))
; ... some wall of text ; ... some wall of text
"))" "))\""
wqdqwf = '(doqwf) wqdqwf = '(doqwf)
var = 1.3 var = 1.3
var = 231 var = 231
qqvwv qqvwv
cfunc()
) )
) )

View File

@ -1,17 +1,34 @@
from collections.abc import Generator
from logging import INFO, basicConfig, getLogger from logging import INFO, basicConfig, getLogger
from re import fullmatch
import re
from time import time from time import time
from lsprotocol.types import ( from lsprotocol.types import (
TEXT_DOCUMENT_DID_CHANGE,
TEXT_DOCUMENT_DID_OPEN, TEXT_DOCUMENT_DID_OPEN,
TEXT_DOCUMENT_DID_SAVE, TEXT_DOCUMENT_DID_SAVE,
TEXT_DOCUMENT_DOCUMENT_SYMBOL, TEXT_DOCUMENT_DOCUMENT_SYMBOL,
TEXT_DOCUMENT_HOVER,
TEXT_DOCUMENT_INLAY_HINT,
CompletionItem, CompletionItem,
Diagnostic,
DiagnosticSeverity,
DidChangeTextDocumentParams,
DidOpenTextDocumentParams, DidOpenTextDocumentParams,
DidSaveTextDocumentParams, DidSaveTextDocumentParams,
DocumentSymbol, DocumentSymbol,
DocumentSymbolParams, DocumentSymbolParams,
Hover,
HoverParams,
InlayHint,
InlayHintParams,
MessageType,
Position,
Range,
) )
from pygls.server import LanguageServer from pygls.server import LanguageServer
from pygls.workspace import TextDocument
from skillls.parsing.iterative import IterativeParser, TokenParser from skillls.parsing.iterative import IterativeParser, TokenParser
@ -24,35 +41,97 @@ basicConfig(filename="skillls.log", level=INFO)
cache: Cache[str, CompletionItem] = Cache() cache: Cache[str, CompletionItem] = Cache()
logger = getLogger(__name__) logger = getLogger(__name__)
server = LanguageServer("skillls", "v0.1")
@server.feature(TEXT_DOCUMENT_DOCUMENT_SYMBOL) class SkillLanguageServer(LanguageServer):
def on_hover(params: DocumentSymbolParams) -> list[DocumentSymbol]: def _diagnose_parens(self, doc: TextDocument) -> Generator[Diagnostic, None, None]:
server.workspace.remove_text_document(params.text_document.uri) open: list[tuple[int, int]] = []
doc = server.workspace.get_text_document(params.text_document.uri) in_str: bool = False
t = TokenParser() last = ""
t.prepare_content(doc.source) for row, line in enumerate(doc.lines):
for col, char in enumerate(line):
match char:
case "(":
if not in_str:
open.append((row, col))
case ")":
if not in_str:
if len(open) > 0:
open.pop()
else:
yield (
Diagnostic(
Range(
Position(row, col),
Position(row, col),
),
"unopened ) encountered",
)
)
case '"':
if not (in_str and last == "\\"):
in_str = not in_str
case _:
last = char
return t._token_tree last = char
if len(open) > 0:
for row, col in open:
yield (
Diagnostic(
Range(Position(row, col), Position(row, col)),
"unclosed ) encountered",
)
)
def _diagnose_cisms(self, doc: TextDocument) -> Generator[Diagnostic, None, None]:
for row, line in enumerate(doc.lines):
for col, char in enumerate(line):
if col > 0:
if fullmatch("\\w", line[col - 1]) and char == "(":
if m := re.match(r"\W+(\w+)$", line[:col]):
tok = m.group(1)
else:
tok = line[col - 1]
yield Diagnostic(
Range(
Position(row, col - len(tok)),
Position(row, col + 1),
),
f"c-ism detected: change to `( {tok}`",
DiagnosticSeverity.Warning,
)
def diagnose(self, doc: TextDocument) -> None:
diags: list[Diagnostic] = []
diags.extend(self._diagnose_parens(doc))
diags.extend(self._diagnose_cisms(doc))
self.publish_diagnostics(doc.uri, diags)
server = SkillLanguageServer("skillls", "v0.2")
@server.feature(TEXT_DOCUMENT_DID_OPEN) @server.feature(TEXT_DOCUMENT_DID_OPEN)
def on_open(params: DidOpenTextDocumentParams) -> None: def on_open(ls: SkillLanguageServer, params: DidOpenTextDocumentParams) -> None:
doc = server.workspace.get_text_document(params.text_document.uri) doc = server.workspace.get_text_document(params.text_document.uri)
p = IterativeParser() ls.diagnose(doc)
diags = p(doc.lines)
server.publish_diagnostics(params.text_document.uri, diags, version=int(time()))
@server.feature(TEXT_DOCUMENT_DID_SAVE) @server.feature(TEXT_DOCUMENT_DID_CHANGE)
def on_save(params: DidSaveTextDocumentParams) -> None: def on_save(ls: SkillLanguageServer, params: DidChangeTextDocumentParams) -> None:
server.workspace.remove_text_document(params.text_document.uri)
doc = server.workspace.get_text_document(params.text_document.uri) doc = server.workspace.get_text_document(params.text_document.uri)
p = IterativeParser() ls.diagnose(doc)
diags = p(doc.lines)
logger.warning(doc.source)
server.publish_diagnostics(params.text_document.uri, diags, version=int(time())) @server.feature(TEXT_DOCUMENT_INLAY_HINT)
def inlay_hints(ls: SkillLanguageServer, params: InlayHintParams) -> list[InlayHint]:
hints: list[InlayHint] = []
return hints
def main(): def main():