坐标属于源码
MSFE 使用 CodeMirror 逻辑文本的 UTF-16 偏移和左闭右开范围 [from, to)。视觉预览没有独立坐标;一张图或一个任务按钮仍对应同一段源码。Emoji 可能占两个 UTF-16 单元,不能用字符数或 DOM 文本偏移替代。
getMarkdown() 可能恢复文件换行策略;计算编辑偏移时使用 editor.state.doc 的逻辑文本,不要对带 CRLF 的保存结果按字节计数。selection.main.from/to 是排序后的范围,anchor/head 保留选择方向。
import { EditorSelection } from '@quirekit/cm-state'
editor.setSelection(EditorSelection.single(10, 18))
editor.scrollTo(10)
editor.focus()
EditorSelection.cursor() 返回单个范围;setSelection 接受完整 EditorSelection,用 single() 或 create() 包装。多选区命令应明确支持全部范围还是拒绝;不能悄悄只改第一处。
短暂菜单:捕获精确目标
const target = editor.captureTarget()
// The host displays a menu; source may change before the user confirms.
const applied = editor.chain(target).insertText('approved').run()
if (!applied) console.warn(editor.lastCommandResult)
目标包含实例、文档、版本和有方向选区。任何源码版本变化都可能使它过期;失败时不能移除 target 后盲目重试,否则会修改新的选区。
等待对话框:映射原始范围
captureAnchor() 可跨无关编辑映射位置,同时验证原范围的文本仍未改变。以下完整函数适合资源选择、异步文本选择等流程;宿主对话框必须尊重 AbortSignal。
import type { MsfeEditor } from "@quirekit/msfe-core";
/** @param editor - Current document. @param choose - Host dialog, observing cancellation. @returns Whether a still-current range was updated. */
export async function replaceSelectionFromDialog(editor: MsfeEditor, choose: (signal: AbortSignal) => Promise<string | null>): Promise<boolean> {
const range = editor.state.selection.main;
const scope = editor.documentScope.fork();
const anchor = editor.captureAnchor({ from: range.from, to: range.to });
scope.own(() => anchor.release());
try {
const value = await choose(scope.signal);
if (scope.disposed || value === null) return false;
const target = anchor.target();
// Unrelated edits may move the interval; changes to its own text invalidate it.
return target ? editor.chain(target).insertText(value).run() : false;
} finally { scope.dispose(); }
}
捕获范围文本已变化、被删除、换文档或已释放时,不再生成有效目标。即使业务复用同一个 documentId,换文档也会结束旧锚点。返回 false 后可以提示用户重新选择,不能强制使用旧偏移。
范围映射策略
默认 inclusiveStart / inclusiveEnd 为 false:恰好插在边界的文本不并入原范围。onDelete: 'drop' 会丢弃完整删除的范围;keep 可将元数据位置保留为点。选择取决于批注、装饰或插入意图的语义,不能套用同一种策略。
SourceRangeSet 适合较多的范围元数据;单个异步用户意图优先用 captureAnchor(),无需自行维护整套位置映射。
与源码显露、搜索和只读协作
原生选区进入普通替换投影时会显露源码;图表的“编辑源码”动作只需设置正确的源码选区。需要完全由控件消费的原子折叠使用专门状态和 interaction: 'atomic',不能借此永久遮挡可搜索内容。