Monaco Editor(Diff Viewer):如何仅显示差异而非完整文件内容?
Monaco Editor Diff Viewer 仅展示变更内容实现方案
这个需求完全可行,核心思路是通过Monaco Editor的Diff API提取所有包含新增、删除、修改的行,过滤掉无变更内容后重新渲染Diff视图。以下是具体实现步骤和代码示例:
实现步骤
获取Diff详细信息
利用Monaco提供的computeDiff方法,计算原始内容与修改后内容的差异,得到包含所有变更范围的结果集。标记需保留的行号
遍历Diff结果,分别收集原始模型和修改模型中所有涉及变更的行号(包括删除行、新增行、修改行)。构建过滤后的内容
从原始和修改内容中提取标记为保留的行,拼接成新的文本内容;如果需要保留上下文,可额外包含变更行前后的指定行数。更新Diff视图
创建新的编辑器模型,替换原Diff Viewer的原始和修改模型,实现仅展示变更内容的效果。
代码示例
// 初始化Diff编辑器 const diffEditor = monaco.editor.createDiffEditor(document.getElementById('diff-container'), { readOnly: true, renderSideBySide: true }); // 原始JSON内容与修改后JSON内容 const originalJson = `{ "name": "demo", "version": "1.0.0", "description": "original content", "scripts": { "start": "node index.js" } }`; const modifiedJson = `{ "name": "demo", "version": "2.0.0", "description": "updated content", "scripts": { "start": "node index.js", "build": "webpack" } }`; // 初始加载完整内容 const originalModel = monaco.editor.createModel(originalJson, 'json'); const modifiedModel = monaco.editor.createModel(modifiedJson, 'json'); diffEditor.setModel({ original: originalModel, modified: modifiedModel }); // 计算差异 const diffResults = monaco.editor.computeDiff(originalJson, modifiedJson, { ignoreTrimWhitespace: false, maxComputationTime: 5000 }); // 收集需保留的行号 const originalKeepLines = new Set(); const modifiedKeepLines = new Set(); diffResults.changes.forEach(change => { // 标记原始模型中被删除/修改的行 if (change.originalStartLineNumber) { for (let i = change.originalStartLineNumber; i <= change.originalEndLineNumber; i++) { originalKeepLines.add(i); } } // 标记修改模型中新增/修改的行 if (change.modifiedStartLineNumber) { for (let i = change.modifiedStartLineNumber; i <= change.modifiedEndLineNumber; i++) { modifiedKeepLines.add(i); } } }); // 生成过滤后的原始内容 const filteredOriginal = originalJson.split('\n') .map((line, idx) => originalKeepLines.has(idx + 1) ? line : '') .filter(line => line) .join('\n'); // 生成过滤后的修改内容 const filteredModified = modifiedJson.split('\n') .map((line, idx) => modifiedKeepLines.has(idx + 1) ? line : '') .filter(line => line) .join('\n'); // 更新Diff视图为仅展示变更内容 const filteredOriginalModel = monaco.editor.createModel(filteredOriginal, 'json'); const filteredModifiedModel = monaco.editor.createModel(filteredModified, 'json'); diffEditor.setModel({ original: filteredOriginalModel, modified: filteredModifiedModel });
补充说明
- 如果需要为变更行保留少量上下文(比如每行前后1行),可以在收集行号时,将
change.originalStartLineNumber - 1、change.originalEndLineNumber + 1等行号也加入集合。 - 为了让用户知晓变更行在原文件中的位置,可以在过滤后的每行开头添加原行号注释,例如
// Line 3:。
内容的提问来源于stack exchange,提问作者Dale Federighi
相关产品推荐
相关产品推荐

