CodeMirror如何在注释或元数据中存储并读取信息
针对你的需求,分CodeMirror 6 和 CodeMirror 5 两个主流版本给出实现方案:
CodeMirror 6 实现
CodeMirror 6 没有直接的行级元数据API,你可以通过**行装饰(Decoration)**或者lineAttrs扩展实现图形ID的存储和读取,比官方的Transaction Annotation更适配行级元数据场景。
步骤1:定义装饰字段存储图形ID
import { Decoration, DecorationSet } from "@codemirror/view" import { StateField, StateEffect } from "@codemirror/state" // 定义给行加图形ID的效果 const addGraphId = StateEffect.define<{ line: number, graphId: string }>() const removeGraphId = StateEffect.define<number>() // 定义存储所有行图形ID的状态字段 export const graphIdField = StateField.define<DecorationSet>({ create() { return Decoration.none }, update(decos, tr) { decos = decos.map(tr.changes) for (const e of tr.effects) { if (e.is(addGraphId)) { const line = tr.state.doc.line(e.value.line) decos = decos.update({ add: [Decoration.line({ attributes: { "data-graph-id": e.value.graphId }, graphId: e.value.graphId }).range(line.from, line.from)] }) } else if (e.is(removeGraphId)) { const line = tr.state.doc.line(e.value) decos = decos.update({ filter: (from, to) => from !== line.from }) } } return decos }, provide: f => EditorView.decorations.from(f) })
步骤2:存储图形ID到指定行
你在解析到绘图指令生成图形ID后,调用下面的代码存到对应行:
editor.dispatch({ effects: addGraphId.of({ line: 3, // 替换为你的指令行号,从1开始计数 graphId: "graph_123" // 替换为你的图形ID }) })
步骤3:删除行时读取图形ID
监听文档变更事件,遍历被删除的行,读取绑定的图形ID:
import { ViewPlugin, ViewUpdate } from "@codemirror/view" const deleteGraphListener = ViewPlugin.fromClass(class { update(update: ViewUpdate) { if (!update.docChanged) return // 遍历所有变更范围 update.changes.iterChanges((fromA, toA) => { const startLine = update.startState.doc.lineAt(fromA) const endLine = update.startState.doc.lineAt(toA) // 遍历所有被删除的行 for (let lineNum = startLine.number; lineNum <= endLine.number; lineNum++) { const line = update.startState.doc.line(lineNum) // 读取该行的装饰元数据 update.startState.field(graphIdField).between(line.from, line.to, (from, to, deco) => { if (deco.spec.graphId) { // 拿到图形ID,调用你的Canvas删除逻辑 console.log("需要删除的图形ID:", deco.spec.graphId) } }) } }) } })
最后把graphIdField和deleteGraphListener加入到编辑器的扩展配置即可。
CodeMirror 5 实现
CodeMirror 5 原生提供了行级元数据的读写API,实现更简单:
存储图形ID
// line参数为行号,默认从1开始计数 editor.setLineData(line, { graphId: "graph_123" })
读取并处理删除行的逻辑
editor.on("beforeChange", (cm, change) => { // 只处理删除操作 if (change.origin !== "+delete") return const startLine = change.from.line const endLine = change.to.line for (let lineNum = startLine; lineNum <= endLine; lineNum++) { const lineMeta = cm.getLineData(lineNum) if (lineMeta?.graphId) { // 拿到图形ID调用Canvas删除逻辑 console.log("需要删除的图形ID:", lineMeta.graphId) } } })
内容的提问来源于stack exchange,提问作者Jadon Erwin
相关产品推荐
相关产品推荐

