ACE编辑器Mermaid图自动补全出现前缀重复问题求助
Ace编辑器Mermaid自动补全重复标记问题解决
问题描述
为Ace编辑器添加Mermaid图自动补全功能,当前实现代码如下:
const mermaids = Object.entries({ "mermaid graph": `graph LR\n x --> y`, }).map(([name, autocompletion]) => ({ caption: name, meta: name, value: "```mermaid\n" + autocompletion + "\n```" })); aceeditor.setOptions({ enableBasicAutocompletion: [{ getCompletions: (editor, session, pos, prefix, callback) => { callback(null, [ ...mermaids ]) } }], enableSnippets: false, enableLiveAutocompletion: true });
遇到的问题:
- 输入
graph或mermaid回车触发补全时,功能正常(仅光标位置需优化); - 输入
回车触发补全时,补全内容会追加在原有之后,导致重复标记,示例如下:
``````mermaid graph LR x --> y
## 高效修正方法 核心思路:在补全逻辑中判断当前输入上下文,动态调整补全内容的格式,避免重复添加```。 修改`getCompletions`函数,检查当前行是否已经输入了```,如果是,则移除补全内容开头的```标记: ```javascript aceeditor.setOptions({ enableBasicAutocompletion: [{ getCompletions: (editor, session, pos, prefix, callback) => { const currentLine = session.getLine(pos.row); // 动态调整补全项的value const adjustedMermaids = mermaids.map(item => { if (currentLine.trim() === "```") { // 去掉开头的```,避免重复 return { ...item, value: item.value.replace(/^```/, '') }; } return item; }); callback(null, adjustedMermaids); } }], enableSnippets: false, enableLiveAutocompletion: true });
补全完成后的兜底处理方案
如果上述方法无法覆盖所有场景,可以通过监听Ace编辑器的change事件,在补全完成后检查并清理重复标记:
editor.on("change", (event) => { const session = editor.getSession(); const { start, end } = event.range; const changedText = event.data.text; // 仅处理包含mermaid标记的插入操作 if (changedText.includes("```mermaid")) { // 检查前一行是否是重复的``` const prevRow = start.row - 1; if (prevRow >= 0) { const prevLine = session.getLine(prevRow); if (prevLine.trim() === "```") { // 删除前一行的重复标记 session.remove({ start: { row: prevRow, column: 0 }, end: { row: prevRow, column: prevLine.length } }); } } } });
更优实现方案:使用Ace代码片段(Snippets)
Ace的Snippets功能支持更灵活的补全控制,包括光标位置、动态替换内容,能更好适配不同触发场景:
- 启用Snippets功能:
aceeditor.setOptions({ enableBasicAutocompletion: true, enableSnippets: true, enableLiveAutocompletion: true });
- 注册针对不同触发词的Mermaid片段:
// 获取编辑器的代码片段管理器 const snippetManager = ace.require("ace/snippets").snippetManager; // 注册针对`graph`和`mermaid`的完整片段 snippetManager.register({ name: "markdown", snippets: [ { caption: "Mermaid Graph", tabTrigger: "graph", snippet: '```mermaid\n graph LR\n ${1:x} --> ${2:y}\n```', description: "Insert a Mermaid flow graph" }, { caption: "Mermaid Graph", tabTrigger: "mermaid", snippet: '```mermaid\n graph LR\n ${1:x} --> ${2:y}\n```', description: "Insert a Mermaid flow graph" }, // 针对```的片段,直接补全mermaid内容和结尾标记 { caption: "Mermaid Graph", tabTrigger: "```", snippet: 'mermaid\n graph LR\n ${1:x} --> ${2:y}\n```', description: "Insert a Mermaid flow graph after triple backticks" } ] });
这种方式不仅能避免重复标记问题,还支持通过Tab键跳转光标到可编辑位置(${1:x}和${2:y}),提升编辑体验。
内容的提问来源于stack exchange,提问作者svidgen
相关产品推荐
相关产品推荐

