diff --git a/language-server/src/build-server.ts b/language-server/src/build-server.ts index c36d51a..522de59 100644 --- a/language-server/src/build-server.ts +++ b/language-server/src/build-server.ts @@ -2,7 +2,8 @@ import "@hyperjump/json-schema/draft-2020-12"; import { TextDocuments } from "vscode-languageserver"; import { TextDocument } from "vscode-languageserver-textdocument"; import { Server } from "./services/server.ts"; -import { JsonValidation } from "./features/JsonValidation.ts"; +import { Diagnostics } from "./features/Diagnostics.ts"; +import { SyntaxValidation } from "./features/SyntaxValidation.ts"; import type { Connection } from "vscode-languageserver"; @@ -15,7 +16,9 @@ export const buildServer = (connection: Connection): Connection => { const documents = new TextDocuments(TextDocument); documents.listen(server); - new JsonValidation(server, documents); + new Diagnostics(server, documents, [ + new SyntaxValidation() + ]); return server; }; diff --git a/language-server/src/features/Diagnostics.ts b/language-server/src/features/Diagnostics.ts new file mode 100644 index 0000000..4228586 --- /dev/null +++ b/language-server/src/features/Diagnostics.ts @@ -0,0 +1,39 @@ +import { TextDocuments, TextDocumentSyncKind } from "vscode-languageserver"; +import { TextDocument } from "vscode-languageserver-textdocument"; +import { Server } from "../services/server.ts"; + +import type { ServerCapabilities, Diagnostic } from "vscode-languageserver"; + +export type DiagnosticsProvider = { + getDiagnostics(textDocument: TextDocument): Diagnostic[]; +}; + +export class Diagnostics { + private providers: DiagnosticsProvider[]; + + constructor(server: Server, documents: TextDocuments, providers: DiagnosticsProvider[]) { + this.providers = providers; + + server.onInitialize(() => { + const serverCapabilities: ServerCapabilities = { + textDocumentSync: TextDocumentSyncKind.Incremental + }; + + return { + capabilities: serverCapabilities + }; + }); + + documents.onDidChangeContent(async (change) => { + const diagnostics = []; + for (const provider of this.providers) { + diagnostics.push(...provider.getDiagnostics(change.document)); + } + + await server.sendDiagnostics({ + uri: change.document.uri, + diagnostics: diagnostics + }); + }); + } +} diff --git a/language-server/src/features/JsonValidation.ts b/language-server/src/features/JsonValidation.ts deleted file mode 100644 index 7a4ab26..0000000 --- a/language-server/src/features/JsonValidation.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { TextDocuments, TextDocumentSyncKind, Diagnostic, DiagnosticSeverity } from "vscode-languageserver"; -import { TextDocument } from "vscode-languageserver-textdocument"; -import * as jsonc from "jsonc-parser"; -import { Server } from "../services/server.ts"; - -import type { ServerCapabilities } from "vscode-languageserver"; - -export class JsonValidation { - constructor(server: Server, documents: TextDocuments) { - server.onInitialize(() => { - const serverCapabilities: ServerCapabilities = { - textDocumentSync: TextDocumentSyncKind.Incremental - }; - - return { - capabilities: serverCapabilities - }; - }); - - documents.onDidChangeContent(async (change) => { - const textDocument = change.document; - const text = textDocument.getText(); - const parseErrors: jsonc.ParseError[] = []; - - jsonc.parseTree(text, parseErrors); - - // for syntax errors - const syntaxDiagnostics: Diagnostic[] = parseErrors.map((error) => ({ - severity: DiagnosticSeverity.Error, - range: { - start: textDocument.positionAt(error.offset), - end: textDocument.positionAt(error.offset + error.length) - }, - message: jsonc.printParseErrorCode(error.error), - source: "json-language-server" - })); - - void server.sendDiagnostics({ - uri: textDocument.uri, - diagnostics: [...syntaxDiagnostics] - }); - }); - } -} diff --git a/language-server/src/features/SyntaxValidation.ts b/language-server/src/features/SyntaxValidation.ts new file mode 100644 index 0000000..4d38626 --- /dev/null +++ b/language-server/src/features/SyntaxValidation.ts @@ -0,0 +1,24 @@ +import { Diagnostic, DiagnosticSeverity } from "vscode-languageserver"; +import { TextDocument } from "vscode-languageserver-textdocument"; +import * as jsonc from "jsonc-parser"; + +import type { DiagnosticsProvider } from "./Diagnostics.ts"; + +export class SyntaxValidation implements DiagnosticsProvider { + getDiagnostics(textDocument: TextDocument): Diagnostic[] { + const text = textDocument.getText(); + const parseErrors: jsonc.ParseError[] = []; + + jsonc.parseTree(text, parseErrors); + + return parseErrors.map((error) => ({ + severity: DiagnosticSeverity.Error, + range: { + start: textDocument.positionAt(error.offset), + end: textDocument.positionAt(error.offset + error.length) + }, + message: jsonc.printParseErrorCode(error.error), + source: "json-language-server" + })); + } +}