问题描述
我正在用Monaco Editor编写自己的IDE。
首先,我有一个诊断程序,可以根据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);
}
}
因为我们可以在悬停的弹出窗口中编写markdown,所以我也使用悬停,它是由先前生成的标记制成的。
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 };
}
但是,在构建标记的过程中,我希望直接根据optimizeformula(text,"A1")
的结果构建悬停的内容。但是我不想再次运行optimizeformula(text,"A1")
。
因此,理想情况下,我想一次在optimizeformula(text,"A1")
中计算 _dovalidate
的结果,将其保存在模型中的某个地方,然后在provideHover
中得到它。
有可能吗?
解决方法
这确实是可能的。请记住:这是Javascript,因此您可以随时添加新属性。通过定义一个新的模型接口,我使用了一个特殊的类来构造模型的内容:
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;
}
然后,我使用特殊的吸气剂从代码编辑器React组件返回增强的编辑器模型:
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;
}