Monaco编辑器注册折叠范围提供者后原有折叠失效求助
解决Monaco编辑器添加JavaScript折叠规则覆盖原有功能的问题
- 问题根源:
monaco.languages.registerFoldingRangeProvider方法会替换目标语言已注册的折叠范围提供者,而非追加。这是Monaco的设计逻辑——同一语言同一类型的提供者默认仅保留最后注册的实例。 - 实现追加折叠规则的具体步骤:
- 先获取JavaScript语言原有的折叠范围提供者:
const originalProvider = monaco.languages.getFoldingRangeProvider('javascript'); - 自定义import语句块折叠逻辑,在
provideFoldingRanges方法中合并原有折叠范围与自定义范围:monaco.languages.registerFoldingRangeProvider('javascript', { async provideFoldingRanges(model, context, token) { // 获取原有折叠范围 let originalRanges = []; if (originalProvider) { originalRanges = await originalProvider.provideFoldingRanges(model, context, token) || []; } // 提取连续的import语句块 const importRanges = []; const lines = model.getLinesContent(); let importStartLine = -1; for (let lineIdx = 0; lineIdx < lines.length; lineIdx++) { const lineContent = lines[lineIdx].trim(); if (lineContent.startsWith('import') && importStartLine === -1) { importStartLine = lineIdx; } else if (importStartLine !== -1 && !lineContent.startsWith('import') && lineContent !== '') { importRanges.push({ start: importStartLine, end: lineIdx - 1, kind: monaco.languages.FoldingRangeKind.Imports }); importStartLine = -1; break; // 仅处理文件顶部连续import块,按需调整逻辑 } } // 处理文件末尾全是import的边界情况 if (importStartLine !== -1) { importRanges.push({ start: importStartLine, end: lines.length - 1, kind: monaco.languages.FoldingRangeKind.Imports }); } // 合并并排序折叠范围 const mergedRanges = [...originalRanges, ...importRanges]; mergedRanges.sort((a, b) => a.start - b.start); return mergedRanges; } }); - 关键注意点:
- 确保在编辑器实例初始化完成后再执行这段代码,避免获取不到原有提供者。
- 可根据
kind或行号去重,防止出现重复折叠块。 - TypeScript场景只需将语言ID替换为
typescript,逻辑完全通用。
- 先获取JavaScript语言原有的折叠范围提供者:
内容的提问来源于stack exchange,提问作者NIge
相关产品推荐
相关产品推荐

