import type { MonacoEditorOptions } from "../types"; import { loadMonaco } from "../utils/loader"; /** * Monaco Editor 封装 */ export class MonacoWrapper { private editor: any | null = null; private monaco: any | null = null; private container: HTMLElement; constructor(container: HTMLElement) { this.container = container; } /** * 初始化编辑器 */ async initialize(options: MonacoEditorOptions = {}): Promise { // 加载 Monaco this.monaco = await loadMonaco(); // 创建编辑器实例 this.editor = this.monaco.editor.create(this.container, { value: options.value || "", language: options.language || "javascript", theme: options.theme || "vs-dark", readOnly: options.readOnly || false, fontSize: options.fontSize || 14, minimap: options.minimap || { enabled: true }, lineNumbers: options.lineNumbers || "on", automaticLayout: options.automaticLayout !== false, scrollBeyondLastLine: false, roundedSelection: true, padding: { top: 16 }, suggestOnTriggerCharacters: options.suggestOnTriggerCharacters !== undefined ? options.suggestOnTriggerCharacters : true, quickSuggestions: options.quickSuggestions !== undefined ? options.quickSuggestions : true, tabSize: 2, }); } /** * 设置值 */ setValue(code: string): void { if (this.editor) { this.editor.setValue(code); } } /** * 获取值 */ getValue(): string { return this.editor ? this.editor.getValue() : ""; } /** * 设置语言 */ /** * 更新模型(切换语言时重建模型以确保语法提示正确) */ updateModel( code: string, language: string, extension: string = "", instanceId: string = "default", ): void { if (this.editor && this.monaco) { const oldModel = this.editor.getModel(); // 构造虚拟文件 URI const ext = extension.startsWith(".") ? extension : `.${extension}`; const uri = this.monaco.Uri.parse(`file:///${instanceId}/main${ext}`); // 查找是否已存在该 URI 的模型 let newModel = this.monaco.editor.getModel(uri); if (!newModel) { newModel = this.monaco.editor.createModel(code, language, uri); } else { newModel.setValue(code); this.monaco.editor.setModelLanguage(newModel, language); } this.editor.setModel(newModel); // 销毁旧模型(如果不再使用,避免内存泄漏。实际项目中可能需要缓存) // 这里为了简单直接销毁旧的(除了新模型就是旧模型的情况) if (oldModel && oldModel !== newModel) { oldModel.dispose(); } } } /** * 设置主题 */ setTheme(theme: string): void { if (this.editor && this.monaco) { this.monaco.editor.setTheme(theme); } } /** * 设置只读 */ setReadOnly(readOnly: boolean): void { if (this.editor) { this.editor.updateOptions({ readOnly }); } } /** * 更新配置 */ updateOptions(options: any): void { if (this.editor) { this.editor.updateOptions(options); } } /** * 监听内容变化 */ onDidChangeContent(callback: (value: string) => void): void { if (this.editor) { this.editor.onDidChangeModelContent(() => { callback(this.getValue()); }); } } /** * 调整布局 */ layout(): void { if (this.editor) { this.editor.layout(); } } /** * 获取 Monaco 实例 */ getMonaco() { return this.monaco; } /** * 获取编辑器实例 */ getEditor() { return this.editor; } /** * 销毁 */ dispose(): void { if (this.editor) { this.editor.dispose(); this.editor = null; } } }