add more complex example
This commit is contained in:
parent
a9ce78c1a3
commit
7b4f3b7119
|
@ -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()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
117
skillls/main.py
117
skillls/main.py
|
@ -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():
|
||||||
|
|
Loading…
Reference in New Issue