0

I'm writing my own IDE by Monaco Editor.

First, I have diagnostics which sets markers from the result of optimizeFormula(text, "A1"):

export class DiagnosticsAdapter {

    private async _doValidate(model: monaco.editor.ITextModel): Promise<void> {
        if (model.isDisposed()) {
            // model was disposed in the meantime
            return;
        }

        const promises: Promise<Diagnostic>[] = [];

        let text = model.getValue();

        let resultA = optimizeFormula(text, "A1");  

        resultA.forEach(resultA1 => {
            promises.push(Promise.resolve({ // see "interface Diagnostic" and "interface DiagnosticRelatedInformation" above
                category: DiagnosticCategory.Warning, // DiagnosticCategory.Suggestion, category: DiagnosticCategory.Error,
                code: utilities.codeFromRule(resultA1.rule), 
                file: undefined,
                length: resultA1.ending - resultA1.start,   
                messageText: utilities.diagnosticMessageFromResult(resultA1),
                start: resultA1.start + 1,
            }))    
        });

        const diagnostics = await Promise.all(promises);

        if (!diagnostics || model.isDisposed()) {
            // model was disposed in the meantime
            return;
        }

        const markers = diagnostics
            .map(d => this._convertDiagnostics(model, d));

        monaco.editor.setModelMarkers(model, this._selector, markers);
    }
}

Because we could write markdown in the popup window of hover, I also use hover, which are made from markers generated earlier.

public async provideHover(model: monaco.editor.ITextModel, position: monaco.Position, token: CancellationToken): Promise<monaco.languages.Hover | undefined> {

        let contents : any[] = [];
        monaco.editor.getModelMarkers({}).forEach(marker => {
        let markerStart = new monaco.Position(marker.startLineNumber, marker.startColumn);
        let markerEnd = new monaco.Position(marker.endLineNumber, marker.endColumn);
            if (markerStart.isBeforeOrEqual(position) && position.isBeforeOrEqual(markerEnd) && marker.code != undefined) {  
                contents.push({ value: utilities.contentMarkdownFromCodeMessage(marker.code, marker.message), isTrusted: false })
            }
        })
        return { contents: contents };
}

Note that the contents of hover are made from markers generated earlier.

However, I would prefer to directly build the contents of hover from the result of optimizeFormula(text, "A1") as how we build markers. But I don't want to run optimizeFormula(text, "A1") once again.

So ideally I would like to calculate the result of optimizeFormula(text, "A1") in _doValidate once for all, save it somewhere in the model, then get it in provideHover.

Is it possible?

Mike Lischke
  • 48,925
  • 16
  • 119
  • 181
SoftTimur
  • 5,630
  • 38
  • 140
  • 292

1 Answers1

0

This is indeed possible. Remember: this is Javascript, so you can add new properties at any time. I did that with a special class to structure the content of the model, by defining a new model interface:

export interface ICodeEditorModel extends Monaco.ITextModel {
    executionBlocks: ExecutionBlocks;
    blockStates?: IExecutionBlocksState[]; // Serializable execution blocks.

    // If the behavior of the model depends on a DB version then this is stored here.
    // Serves as default for all SQL scripting blocks, if they don't have an own version.
    version: number;
}

Then I use a special getter to return the enhanced editor model from my code editor React component:

    private get model(): ICodeEditorModel | undefined {
        if (this.editorRef.current && this.editorRef.current.editor) {
            const model = this.editorRef.current.editor.getModel();
            if (model === null) {
                return undefined;
            }

            return model as ICodeEditorModel;
        }

        return undefined;
    }
Mike Lischke
  • 48,925
  • 16
  • 119
  • 181