如何在VSCode CustomTextEditor扩展中集成Monaco Editor并启用典型功能?
在VS Code Custom Text Editor扩展中集成Monaco Editor(带行号、概览功能)
嘿,我刚好折腾过把Monaco集成到Custom Text Editor里,完全能实现你要的增强版编辑器效果。下面是从零开始的完整步骤:
1. 初始化Custom Text Editor扩展项目
首先用Yeoman生成器创建基础扩展结构:
- 全局安装Yeoman和VS Code扩展生成器:
npm install -g yo generator-code - 运行
yo code,选择New Custom Text Editor,按提示填项目信息(比如命名为monaco-enhanced-editor)
生成项目后,安装专门适配VS Code扩展的Monaco包:
npm install @vscode/monaco-editor --save
2. 配置package.json
确保你的package.json里正确注册自定义编辑器的基础信息,重点关注contributes.customEditors和activationEvents:
{ "activationEvents": [ "onCustomEditor:monaco-enhanced-editor.customEditor" ], "contributes": { "customEditors": [ { "viewType": "monaco-enhanced-editor.customEditor", "displayName": "Enhanced Monaco Editor", "selector": [ { "filenamePattern": "*.monaco" } ], "priority": "default" } ] } }
这里我们指定.monaco后缀的文件默认用这个自定义编辑器打开。
3. 实现Custom Editor Provider(核心逻辑)
打开生成的src/extension.ts,修改CustomTextEditorProvider类,核心是在resolveCustomTextEditor方法中创建WebView并加载Monaco:
先导入必要模块:
import * as vscode from 'vscode'; import { Uri } from 'vscode'; import { getMonacoEnvironment } from '@vscode/monaco-editor';
然后修改resolveCustomTextEditor方法,处理WebView配置和内容同步:
async resolveCustomTextEditor( document: vscode.TextDocument, webviewPanel: vscode.WebviewPanel, _token: vscode.CancellationToken ): Promise<void> { // 配置WebView权限,允许脚本和访问扩展资源 webviewPanel.webview.options = { enableScripts: true, localResourceRoots: [ this.context.extensionUri, Uri.joinPath(this.context.extensionUri, 'node_modules', 'monaco-editor') ] }; // 设置WebView的HTML内容,加载Monaco并初始化编辑器 webviewPanel.webview.html = this.getWebviewContent(webviewPanel.webview, document); // 监听VS Code文档变化,同步到Monaco编辑器 const changeDocumentSubscription = vscode.workspace.onDidChangeTextDocument(e => { if (e.document.uri.toString() === document.uri.toString()) { webviewPanel.webview.postMessage({ type: 'updateDocument', content: e.document.getText() }); } }); // 监听Monaco编辑器内容变化,同步回VS Code文档 webviewPanel.webview.onDidReceiveMessage(async message => { if (message.type === 'updateContent') { const edit = new vscode.WorkspaceEdit(); edit.replace( document.uri, new vscode.Range(0, 0, document.lineCount, 0), message.content ); await vscode.workspace.applyEdit(edit); } }); // 面板关闭时清理订阅 webviewPanel.onDidDispose(() => { changeDocumentSubscription.dispose(); }); }
接下来实现getWebviewContent方法,生成加载Monaco的HTML:
private getWebviewContent(webview: vscode.Webview, document: vscode.TextDocument): string { // 获取Monaco资源的WebView URI const monacoUri = webview.asWebviewUri( Uri.joinPath(this.context.extensionUri, 'node_modules', 'monaco-editor') ); const env = getMonacoEnvironment(monacoUri); return ` <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> body, html { margin: 0; padding: 0; height: 100vh; overflow: hidden; } #container { width: 100%; height: 100%; } </style> </head> <body> <div id="container"></div> <script> // 配置Monaco环境 self.MonacoEnvironment = ${JSON.stringify(env)}; </script> <script src="${monacoUri}/min/vs/loader.js"></script> <script> require.config({ paths: { 'vs': '${monacoUri}/min/vs' } }); require(['vs/editor/editor.main'], () => { // 初始化Monaco编辑器,配置行号、概览等核心功能 const editor = monaco.editor.create(document.getElementById('container'), { value: ${JSON.stringify(document.getText())}, language: 'javascript', // 可根据需求修改语言 lineNumbers: 'on', // 显示左侧行号 overviewRulerLanes: 2, // 右侧概览标尺车道数 overviewRulerBorder: true, // 显示概览标尺边框 scrollBeyondLastLine: false, minimap: { enabled: true }, // 启用迷你地图(和概览配合) theme: 'vs-dark' // 可选:深色主题,也可用'vs'或'hc-black' }); // 监听编辑器内容变化,同步回VS Code editor.onDidChangeModelContent(() => { window.vscode.postMessage({ type: 'updateContent', content: editor.getValue() }); }); // 监听VS Code文档更新,同步到编辑器 window.addEventListener('message', event => { if (event.data.type === 'updateDocument') { const currentValue = editor.getValue(); if (currentValue !== event.data.content) { editor.setValue(event.data.content); } } }); }); </script> </body> </html> `; }
4. 配置高级功能(可选)
如果需要更多增强效果,可以在编辑器初始化的options里添加:
lineNumbersMinChars: 设置行号的最小宽度overviewRulerColor: 自定义概览标尺颜色scrollbar: 配置滚动条样式,比如scrollbar: { vertical: 'visible', horizontal: 'visible' }- 代码高亮、智能提示:需要配置Monaco对应的语言服务
5. 测试扩展
- 按F5启动扩展开发宿主窗口
- 创建一个
test.monaco文件,双击打开就能看到带行号和右侧概览的Monaco编辑器 - 编辑内容会实时同步到文件,修改文件内容也会同步到编辑器
内容的提问来源于stack exchange,提问作者FireFuro99




