| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- import * as monaco from 'monaco-editor'
- import type { LogWorker } from './worker/logWorker'
- export type WorkerAccessor<T> = (...uris: monaco.Uri[]) => Promise<T>
- export abstract class Adapter {
- constructor(protected _worker: (...uris: monaco.Uri[]) => Promise<LogWorker>) {}
- }
- //#region DiagnosticsAdapter
- export interface ILanguageWorkerWithDiagnostics {
- doValidation(uri: string): Promise<monaco.editor.IMarkerData[]>
- }
- export class DiagnosticsAdapter<T extends ILanguageWorkerWithDiagnostics> {
- protected readonly _disposables: monaco.IDisposable[] = []
- private readonly _listener: { [uri: string]: monaco.IDisposable } = Object.create(null)
- constructor(
- private readonly _languageId: string,
- protected readonly _worker: WorkerAccessor<T>,
- ) {
- const onModelAdd = (model: monaco.editor.IModel): void => {
- let modeId = model.getLanguageId()
- if (modeId !== this._languageId) {
- return
- }
- let handle: number
- this._listener[model.uri.toString()] = model.onDidChangeContent(() => {
- window.clearTimeout(handle)
- handle = window.setTimeout(() => this._doValidate(model.uri, modeId), 500)
- })
- this._doValidate(model.uri, modeId)
- }
- const onModelRemoved = (model: monaco.editor.IModel): void => {
- monaco.editor.setModelMarkers(model, this._languageId, [])
- let uriStr = model.uri.toString()
- let listener = this._listener[uriStr]
- if (listener) {
- listener.dispose()
- delete this._listener[uriStr]
- }
- }
- this._disposables.push(monaco.editor.onDidCreateModel(onModelAdd))
- this._disposables.push(monaco.editor.onWillDisposeModel(onModelRemoved))
- this._disposables.push(
- monaco.editor.onDidChangeModelLanguage((event) => {
- onModelRemoved(event.model)
- onModelAdd(event.model)
- }),
- )
- this._disposables.push({
- dispose: () => {
- monaco.editor.getModels().forEach(onModelRemoved)
- for (let key in this._listener) {
- this._listener[key].dispose()
- }
- },
- })
- monaco.editor.getModels().forEach(onModelAdd)
- }
- public dispose(): void {
- this._disposables.forEach((d) => d && d.dispose())
- this._disposables.length = 0
- }
- private _doValidate(resource: monaco.Uri, languageId: string): void {
- this._worker(resource)
- .then((worker) => {
- return worker.doValidation(resource.toString())
- })
- .then((diagnostics) => {
- const markers = diagnostics
- let model = monaco.editor.getModel(resource)
- if (model && model.getLanguageId() === languageId) {
- monaco.editor.setModelMarkers(model, 'LogWorker', markers)
- }
- })
- .then(undefined, (err) => {
- console.error(err)
- })
- }
- }
- // --- inlay hints ----
- export class InlayHintsAdapter extends Adapter implements monaco.languages.InlayHintsProvider {
- public async provideInlayHints(
- model: monaco.editor.ITextModel,
- range: monaco.Range,
- token: monaco.CancellationToken,
- ): Promise<monaco.languages.InlayHintList | null> {
- const resource = model.uri
- const fileName = resource.toString()
- const start = model.getOffsetAt({
- lineNumber: range.startLineNumber,
- column: range.startColumn,
- })
- const end = model.getOffsetAt({
- lineNumber: range.endLineNumber,
- column: range.endColumn,
- })
- const worker = await this._worker(resource)
- if (model.isDisposed()) {
- return null
- }
- const logHints = await worker.provideInlayHints(fileName, start, end)
- const hints: monaco.languages.InlayHint[] = logHints.map((hint) => {
- return {
- ...hint,
- label: hint.label,
- position: hint.position,
- kind: hint.kind,
- }
- })
- return { hints, dispose: () => {} }
- }
- }
|