diff --git a/packages/libro-language-client/src/common/vscodeAdaptor/diagnosticCollection.ts b/packages/libro-language-client/src/common/vscodeAdaptor/diagnosticCollection.ts index 5ed3dd8a..a135bde9 100644 --- a/packages/libro-language-client/src/common/vscodeAdaptor/diagnosticCollection.ts +++ b/packages/libro-language-client/src/common/vscodeAdaptor/diagnosticCollection.ts @@ -1,12 +1,15 @@ import { DisposableCollection } from '@difizen/mana-app'; -import type * as monaco from '@difizen/monaco-editor-core'; import { MarkerSeverity } from '@difizen/monaco-editor-core'; +import * as monaco from '@difizen/monaco-editor-core'; +import type { editor } from '@difizen/monaco-editor-core'; import type { DiagnosticCollection } from 'vscode'; -import type { Diagnostic, Uri } from 'vscode'; +import type { Diagnostic, Uri, Disposable } from 'vscode'; import { URI } from 'vscode-uri'; -import type { ResourceMap } from './hostTypeUtil.js'; -import type { ProtocolToMonacoConverter } from './monaco-converter.js'; +import * as c2p from '../codeConverter.js'; + +import { ResourceMap } from './hostTypeUtil.js'; +import { ProtocolToMonacoConverter } from './monaco-converter.js'; import { DiagnosticSeverity, EventEmitter } from './vscodeAdaptor.js'; export class LibroDiagnosticCollection implements DiagnosticCollection { @@ -15,9 +18,13 @@ export class LibroDiagnosticCollection implements DiagnosticCollection { private readonly _maxDiagnosticsPerFile: number = 1000; private readonly _maxDiagnosticsTotal: number = 1.1 * this._maxDiagnosticsPerFile; + protected readonly c2p: c2p.Converter = c2p.createConverter(); + protected readonly p2m: ProtocolToMonacoConverter = new ProtocolToMonacoConverter( + monaco, + ); name: string; - readonly #data: ResourceMap; + readonly #data: ResourceMap = new ResourceMap(); private _isDisposed = false; set(uri: Uri, diagnostics: ReadonlyArray): void; set(entries: ReadonlyArray<[Uri, ReadonlyArray]>): void; @@ -85,10 +92,10 @@ export class LibroDiagnosticCollection implements DiagnosticCollection { // if (!this.#proxy) { // return; // } - const entries: [URI, IMarkerData[]][] = []; + const entries: [URI, editor.IMarkerData[]][] = []; let totalMarkerCount = 0; for (const uri of toSync) { - let marker: IMarkerData[] = []; + let marker: editor.IMarkerData[] = []; const diagnostics = this.#data.get(uri); if (diagnostics) { // no more than N diagnostics per file @@ -103,10 +110,8 @@ export class LibroDiagnosticCollection implements DiagnosticCollection { orderLoop: for (let i = 0; i < 4; i++) { for (const diagnostic of diagnostics) { if (diagnostic.severity === order[i]) { - const len = marker.push({ - ...converter.Diagnostic.from(diagnostic), - modelVersionId: this._modelVersionIdProvider(uri), - }); + const diag = this.p2m.asDiagnostic(this.c2p.asDiagnostic(diagnostic)); + const len = marker.push(diag); if (len === this._maxDiagnosticsPerFile) { break orderLoop; } @@ -117,29 +122,25 @@ export class LibroDiagnosticCollection implements DiagnosticCollection { // add 'signal' marker for showing omitted errors/warnings marker.push({ severity: MarkerSeverity.Info, - message: localize( - { - key: 'limitHit', - comment: ['amount of errors/warning skipped due to limits'], - }, - 'Not showing {0} further errors and warnings.', - diagnostics.length - this._maxDiagnosticsPerFile, - ), + message: `Not showing ${diagnostics.length - this._maxDiagnosticsPerFile} further errors and warnings.`, startLineNumber: marker[marker.length - 1].startLineNumber, startColumn: marker[marker.length - 1].startColumn, endLineNumber: marker[marker.length - 1].endLineNumber, endColumn: marker[marker.length - 1].endColumn, }); } else { - marker = diagnostics.map((diag) => ({ - ...converter.Diagnostic.from(diag), - modelVersionId: this._modelVersionIdProvider(uri), - })); + marker = diagnostics.map((diag) => { + const mark = this.p2m.asDiagnostic(this.c2p.asDiagnostic(diag)); + return mark; + }); } } entries.push([uri, marker]); + // update monaco + this.updateModelMarkers(uri, marker); + totalMarkerCount += marker.length; if (totalMarkerCount > this._maxDiagnosticsTotal) { // ignore markers that are above the limit @@ -216,6 +217,13 @@ export class LibroDiagnosticCollection implements DiagnosticCollection { } } + updateModelMarkers(uri: Uri, markers: editor.IMarkerData[]): void { + const model = monaco.editor.getModel(uri); + if (model) { + monaco.editor.setModelMarkers(model, this.name, markers); + } + } + dispose(): void { if (!this._isDisposed) { this.#onDidChangeDiagnostics.fire([...this.#data.keys()]); @@ -237,6 +245,7 @@ export class MonacoModelDiagnostics implements Disposable { diagnostics: Diagnostic[], readonly owner: string, protected readonly p2m: ProtocolToMonacoConverter, + protected readonly c2p: c2p.Converter, ) { this.uri = this._monaco.Uri.parse(uri); this.diagnostics = diagnostics; @@ -247,8 +256,16 @@ export class MonacoModelDiagnostics implements Disposable { set diagnostics(diagnostics: Diagnostic[]) { this._diagnostics = diagnostics; - this._markers = this.p2m.asDiagnostics(diagnostics); - this.updateModelMarkers(); + this.c2p + .asDiagnostics(diagnostics) + .then((diag) => { + this._markers = this.p2m.asDiagnostics(diag); + this.updateModelMarkers(); + return; + }) + .catch(() => { + // + }); } get diagnostics(): Diagnostic[] { diff --git a/packages/libro-language-client/src/common/vscodeAdaptor/monacoLanguages.ts b/packages/libro-language-client/src/common/vscodeAdaptor/monacoLanguages.ts index a50e4cea..add23b20 100644 --- a/packages/libro-language-client/src/common/vscodeAdaptor/monacoLanguages.ts +++ b/packages/libro-language-client/src/common/vscodeAdaptor/monacoLanguages.ts @@ -42,12 +42,13 @@ import type { InlayHintsProvider, } from 'vscode'; +import { LibroDiagnosticCollection } from './diagnosticCollection.js'; import { IMonacoLanguages } from './services.js'; @singleton({ token: IMonacoLanguages }) export class MonacoLanguages implements IMonacoLanguages { createDiagnosticCollection(name?: string): DiagnosticCollection { - return {} as DiagnosticCollection; + return new LibroDiagnosticCollection(); } match(selector: DocumentSelector, document: TextDocument): number { // const notebook = extHostDocuments.getDocumentData(document.uri)?.notebook;