You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Monaco Editor(Diff Viewer):如何仅显示差异而非完整文件内容?

Monaco Editor Diff Viewer 仅展示变更内容实现方案

这个需求完全可行,核心思路是通过Monaco Editor的Diff API提取所有包含新增、删除、修改的行,过滤掉无变更内容后重新渲染Diff视图。以下是具体实现步骤和代码示例:

实现步骤

  1. 获取Diff详细信息
    利用Monaco提供的computeDiff方法,计算原始内容与修改后内容的差异,得到包含所有变更范围的结果集。

  2. 标记需保留的行号
    遍历Diff结果,分别收集原始模型和修改模型中所有涉及变更的行号(包括删除行、新增行、修改行)。

  3. 构建过滤后的内容
    从原始和修改内容中提取标记为保留的行,拼接成新的文本内容;如果需要保留上下文,可额外包含变更行前后的指定行数。

  4. 更新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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 05:44:55