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

Monaco编辑器如何基于模型自定义行号?解决peek视图行号异常

Monaco编辑器自定义行号在Peek视图中的问题

我正在使用Monaco编辑器展示自定义文件类型,需要基于模型自定义显示行号——单个模型时功能正常,但打开Peek视图查看其他模型/文件定义时出现问题:

  • 文件内容的显示行号并非总是从同一数字开始
  • 部分物理行不应被计数,旁边不应显示行号

我按照官方示例设置了lineNumbersFunc自定义行号,但这个函数对所有显示的文件/模型都生效,不符合需求。我尝试在函数内用editor.getModel(),但它始终返回初始模型,而非Peek视图中的模型。

补充说明:在Playground示例中点击代码透镜后,Peek视图的行号显示不正确(截图显示Peek视图中文件的行号未按预期显示)

问题:

  1. 是否有其他方式可以基于模型指定行号?
  2. 能否在lineNumbersFunc中获取该行号对应的模型?

解决方案

1. 基于模型绑定专属行号逻辑

Monaco的lineNumbersFunc无法直接获取当前渲染的模型,但可以通过模型自定义属性+全局映射表实现模型专属规则:

  • 用WeakMap存储模型与行号配置的映射(避免内存泄漏):
    const modelLineConfigMap = new WeakMap<monaco.editor.ITextModel, { startLine: number; hiddenLines: Set<number> }>();
    
  • 给目标模型绑定自定义行号配置:
    function bindLineNumberConfig(model: monaco.editor.ITextModel, config) {
        modelLineConfigMap.set(model, config);
    }
    

2. 在lineNumbersFunc中获取对应模型

editor.getModel()仅返回主编辑器模型,但可以通过Peek视图的内部服务获取当前活跃的嵌套编辑器,进而拿到对应模型:

const lineNumbersFunc = (lineNumber: number, editor: monaco.editor.IStandaloneCodeEditor) => {
    // 获取Peek视图的活跃编辑器,无则使用主编辑器
    const activeEditor = editor.getContribution('editor.contrib.peekViewService')?.getActivePeekEditor() || editor;
    const currentModel = activeEditor.getModel();
    
    if (!currentModel) return String(lineNumber);
    
    const config = modelLineConfigMap.get(currentModel);
    if (!config) return String(lineNumber);
    
    // 隐藏指定行的行号
    if (config.hiddenLines.has(lineNumber)) return '';
    // 计算偏移后的显示行号
    return String(lineNumber - 1 + config.startLine);
};

3. 备选方案:用装饰器实现自定义行号

如果lineNumbersFunc的限制无法满足需求,可使用Monaco的装饰器API完全自定义行号渲染:

  • 创建装饰器规则,给目标行添加自定义行号元素
  • 监听模型切换、内容变更事件,动态更新装饰器

内容的提问来源于stack exchange,提问作者Matt Lacey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 10:30:54