本页签名从公共包导出生成,中文说明与当前 JSDoc 同步校验。代码标识保持原名。
命令上下文
命令必须纯粹、同步;嵌套操作使用 props.commands,见 命令教程。
@quirekit/msfe-core纯命令执行上下文;所有嵌套操作共用同一个事务草稿。
export interface CommandProps {
readonly state: EditorState;
readonly tr: SourceTransaction;
readonly editor: MsfeEditor;
readonly commands: SingleCommands;
readonly dispatch: (() => void) | undefined;
chain(): ChainedCommands;
can(): SingleCommands;
}源码事务
每一步坐标属于当前草稿,不能使用原始文档的过期偏移。
@quirekit/msfe-coreMSFE 源码事务构建器,使用 CodeMirror 状态和源码偏移。
export interface SourceTransaction {
readonly state: EditorState;
insertText(text: string): boolean;
replace(from: number, to: number, insert: string): boolean;
setSelection(anchor: number, head?: number): boolean;
effect<T>(effect: Effect<T>, value: T): boolean;
setMeta<T>(metadata: Metadata<T>, value: T): boolean;
apply(spec: TransactionSpec): boolean;
}适配规划函数
把现有 CodeMirror 纯规划函数接入相同的命令链。
@quirekit/msfe-core将纯 CodeMirror 规划函数适配到源码命令事务。参数 planner:底层规划函数。返回可用于 addCommands 或 chain.command 的命令。
function sourceCommand(planner: MsfeCommand): Command语义格式命令
toggleSourceMark({ node: 'StrongEmphasis', marker: '**', markerNode: 'EmphasisMark' })
返回可交给 editor.run() 或 sourceCommand() 的纯规划函数。功能包声明语法,Core 统一处理
成对标记、方向选区和完整外壳;一次执行同时确认新增格式和原有成对语义仍能解析。
完整正文选区可以扩展到隐藏外壳;没有可证明无损的方案就返回 null,不改源码或历史。
局部移除格式和交错范围暂不自动拆分。空选区保留插入成对标记的输入方式,后续输入仍是自由源码。
querySourceInline(state, range) 只读端点祖先,不启动解析、遍历全文或执行格式命令,适合界面可用性。
reason === null 仅表示结构允许,不能预先保证具体样式组合可行;空白正文可没有节点。
显式规划限制在一个不超过 20,000 字符的行内容器,解析验证预算为 12ms;无法及时验证也拒绝。
所有多选区先规划,再原子提交。低层 toggleDelimiter 仍只是字面源码工具。
@quirekit/msfe-core语义格式功能声明的语法节点与源码标记。
export interface SourceMarkFormat {
readonly node: string;
readonly marker: string;
readonly markerNode: string;
}@quirekit/msfe-core共同的行内容器,以及拒绝格式操作的结构原因。
export interface SourceInlineQuery {
readonly node: SyntaxNode | null;
readonly reason: "readonly" | "unparsed" | "structure" | "literal" | "selection" | null;
}@quirekit/msfe-core只读取源码端点和祖先,不启动解析或序列化。参数 state:当前源码状态。参数 range:目标范围。返回共同的行内容器或结构性拒绝原因。
function querySourceInline(state: EditorState, range: { readonly from: number; readonly to: number; }): SourceInlineQuery@quirekit/msfe-core基于当前解析器切换格式,保持 Markdown 文本权威。参数 format:功能声明的节点与标记。返回纯规划命令;不能保留语义时不修改源码或历史。
function toggleSourceMark(format: SourceMarkFormat): MsfeCommand结果分支
具名命令返回 boolean;详细结果读取 lastCommandResult。
@quirekit/msfe-core明确返回成功或拒绝原因;不会自动把过期用户意图转移到新位置。
export type MsfeResult = {
readonly ok: true;
} | {
readonly ok: false;
readonly reason: "destroyed" | "not-mounted" | "readonly" | "stale-target" | "not-applicable" | "invalid-change" | "composing" | "not-installed" | "source-provider-locked";
};外部增量
baseRevision 是本地源码版本,不是服务器 ETag。
@quirekit/msfe-core携带基础版本的外部源码修改。
export interface MsfeExternalChange {
readonly documentId: string;
readonly baseRevision: number;
readonly changes: ChangeSpec;
readonly origin?: string;
}精确目标
适合短暂菜单;源码版本变化后可能失效。
@quirekit/msfe-core捕获工具栏动作开始时的目标,仅对该实例、文档及精确版本有效。
export interface MsfeTarget {
readonly instanceId: string;
readonly documentId: string;
readonly revision: number;
readonly selection: EditorSelection;
}映射目标
异步处理完整示例见 选区与异步目标。
@quirekit/msfe-core限定于当前文档生命周期、可随修改映射位置的操作意图。
export interface SourceAnchor {
getRange(): MsfeSourceRange | null;
target(): MsfeTarget | null;
release(): void;
}映射策略
按功能选择边界亲和性和删除策略,不改变视觉结构。
@quirekit/msfe-core定义边界插入和删除时如何映射位置,与视觉样式无关。
export interface RangePolicy {
readonly inclusiveStart?: boolean;
readonly inclusiveEnd?: boolean;
readonly onDelete?: "drop" | "keep";
}源码块命令
定位完整语法块,并通过捕获的 MsfeTarget 运行命令。规划器保留源码片段、一次撤销,拒绝跨子流移动。
@quirekit/msfe-core完整源码块及其同级内容范围,不创建第二份文档模型。
export interface SourceBlock extends MsfeSourceRange {
readonly name: string;
readonly scope: MsfeSourceRange;
}@quirekit/msfe-core相对于完整块的插入方向:上方或下方。
export type SourceBlockSide = "before" | "after";@quirekit/msfe-core只查询指针或光标所在的祖先链,不扫描兄弟内容。参数 state:已接受源码及解析快照。参数 position:块内逻辑位置。参数 scope:可选的同级范围,用于把嵌套落点提升到同一层。返回最近的完整可操作块。
function sourceBlockAt(state: EditorState, position: number, scope?: SourceBlock["scope"]): SourceBlock | null@quirekit/msfe-core参数 state:当前解析快照。参数 block:完整块。参数 direction:上一个(-1)或下一个(1)。返回相邻结构块,不枚举整篇文档。
function sourceBlockSibling(state: EditorState, block: SourceBlock, direction: -1 | 1): SourceBlock | null@quirekit/msfe-core参数 a、b:两个源码块。返回两者是否属于完全相同的同级内容范围。
function sameSourceBlockScope(a: SourceBlock, b: SourceBlock): boolean@quirekit/msfe-core参数 block:明确的邻接块。参数 side:插入方向。参数 markdown:完整 Markdown。返回原子插入规划器,保留内容中的原始分隔标记。
function insertSourceBlock(block: SourceBlock, side: SourceBlockSide, markdown: string): MsfeCommandreplaceSourceBlock(block, markdown) 用新 Markdown 一次替换完整块,保留必要的相邻分隔符,
并校验外层容器边界。通过 editor.run(command, capturedTarget) 执行,以拒绝过时菜单意图。
@quirekit/msfe-core参数 block:捕获的完整源码块。参数 markdown:规范的替换内容。返回原子替换规划器,重新校验块归属并保留同级分隔与容器边界。
function replaceSourceBlock(block: SourceBlock, markdown: string): MsfeCommand@quirekit/msfe-core可插入内容流中的空白物理行,不创建虚假的语法节点。
export interface SourceBlankLine extends MsfeSourceRange {
readonly scope: MsfeSourceRange;
}@quirekit/msfe-core参数 state:当前源码与语法。参数 position:指针或光标位置。返回可插入内容流中的空行;代码或列表语法内部空白不作为插入位置。
function sourceBlankLineAt(state: EditorState, position: number): SourceBlankLine | null@quirekit/msfe-core参数 line:已捕获的可编辑空行。参数 markdown:完整的标准源码。返回受保护的替换命令,保留同级块分隔与外层容器。
function insertAtSourceBlankLine(line: SourceBlankLine, markdown: string): MsfeCommand@quirekit/msfe-core参数 block:捕获的完整块。返回在命令草稿中重新校验的源码删除规划器。
function removeSourceBlock(block: SourceBlock): MsfeCommand@quirekit/msfe-core通过 editor.run 移动精确源码,只提交一次事务、产生一次撤销事件。参数 block:手势开始时捕获的块。参数 target:最终指针位置的完整同级块。参数 side:目标前后方向。返回拒绝自身、后代、跨范围或过期目标的规划器。
function moveSourceBlock(block: SourceBlock, target: SourceBlock, side: SourceBlockSide): MsfeCommand编辑边界
插件用 addEditingBoundaries()(或 descriptor 的 editingBoundaries)声明隐藏源码的
语义范围。宿主 MdEditor / createMdEditor / createMdEditorExtensions 的同名选项可
按节点覆盖默认规则;完整接入示例见 光标与编辑边界。
这份声明用于导航、选区和正文输入保护;Enter、Shift-Enter 和 Mod-Enter 的结构操作由
下面的 addBlockInput() 合同承担。
范围和策略
所有偏移属于当前 state.doc。必须满足
0 ≤ from ≤ contentFrom ≤ contentTo ≤ to ≤ state.doc.length;可选的
selectFrom/selectTo 必须覆盖 from/to 且在文档内。非法范围在解析规则时抛出
invalid-editing-boundary 错误;无法确认语法时应返回 null。
kind | 语义与常见用法 |
|---|---|
style | 加粗、斜体、代码、链接等行内格式,正文在成对外壳内部 |
block | 代码、容器等块,外壳保护包含保持结构所需的相邻换行 |
prefix | 标题、列表、引用等结构前缀,光标进入前缀后的正文 |
separator | 压缩的结构间隔,导航跳过;产品允许原生删除以合并正文 |
syntax | 表格竖线或对齐行等结构字符,selectFrom/selectTo 可指向完整表格 |
atom | 整体组件或空围栏,光标不进入内部,边缘删除先选中整体 |
navigation: 'content' 是默认的行内进入策略,split 保留样式内外两侧。
块显式声明 content 时,原生行首、行尾端点收敛到块内内容,适用于表格行的外侧竖线;
左右键仍通过公共导航越过重复端点,删除保护不变。未声明时保留块的默认跨外壳导航。
当前 navigation: 'native' 使整条语法规则退出公共运行时,包括它的编辑保护。
deletion: 'unwrap' 在对应边缘移除完整样式或前缀;protect 保留外壳;
deletion: 'native' 仅委托编辑处理,仍保留导航规则。建议显式声明删除策略。
完整选中所属结构允许整体删除,部分选区保留其外壳。
@quirekit/msfe-core隐藏源码的完整结构范围及可编辑正文;不创建第二份内容模型。
export interface EditingBoundary {
readonly from: number;
readonly to: number;
readonly contentFrom: number;
readonly contentTo: number;
readonly kind: EditingBoundaryKind;
readonly selectFrom?: number;
readonly selectTo?: number;
readonly navigation?: "content" | "split" | "native";
readonly deletion?: "unwrap" | "protect" | "native";
}@quirekit/msfe-core隐藏源码的语义归属,独立于 DOM 装饰形状。
export type EditingBoundaryKind = "style" | "block" | "prefix" | "separator" | "syntax" | "atom";查询和优先级
nodes 使用解析器节点名称。resolve 是当前源码上的纯查询,不能 dispatch、保留旧
节点偏移或按显示行数猜测位置。普通导航只查询端点与祖先,编辑查询本次变更覆盖的
语法;自定义查询也应保持对应的工作范围。
同一节点只采用按扩展优先级排序后的第一条规则,宿主覆盖在功能默认规则之前。
规则整体替换,不逐字段合并;返回 null 会退出该语法规则,不回退到下一条。
已物化的块组件独立贡献整体对象范围,并覆盖其内部语法规则。
默认 when: 'hidden' 仅在整体隐藏语法的呈现中启用。when: 'prose' 扩展到 Markdown
编辑呈现;需要保护未显露代码等结构时,先用 isSourceRevealed(state, node) 检查
具体范围,显露时返回 null。源码模式与组合输入期间不执行边界归一化。
@quirekit/msfe-core功能提供的边界事实,由公共导航与编辑运行时统一消费。
export interface EditingBoundaryRule {
readonly nodes: readonly string[];
readonly when?: "hidden" | "prose";
readonly resolve: (context: EditingBoundaryContext) => EditingBoundary | null;
}@quirekit/msfe-core针对一个规范源码端点的纯功能查询上下文。
export interface EditingBoundaryContext {
readonly state: EditorState;
readonly node: SyntaxNode;
readonly position: number;
}安装与生命周期
一般插件使用 addEditingBoundaries() 自动接入。高级 CM 集成可在
addCodeMirrorExtensions() 中安装 editingBoundaries(rules);重复安装共享同一执行层。
rules 为空时返回空扩展,不卸载其他插件的规则。MD Editor 的 editingBoundaries: []
也保留默认规则;配置只在创建时读取,Vue prop 更新不自动重装规则。
输入保护在接受事务前生成完整变更,保留 annotations 并映射 effects;移动光标不写源码 或增加历史。显式结构命令、外部文档更新与历史恢复保持自身权限;绕过过滤器的事务 只在需要时恢复合法选区,并检查当前状态身份和实例是否已销毁。只读不接受正文写入。
@quirekit/msfe-core参数 rules:功能拥有的语法范围规则,高优先级在前。返回:共享导航、输入保护与端点恢复扩展;重复安装复用同一个运行时。
function editingBoundaries(rules: readonly EditingBoundaryRule[]): Extension块级回车
扩展通过 addBlockInput() 声明语法块的输入归属;参见 命令教程。planBlockInput 是纯规划入口,返回 null 时由调用方保留原生处理。
@quirekit/msfe-core语法节点的唯一输入所有者;省略意图时委托父级,未注册的块节点终止分派。
export interface BlockInputRule {
readonly nodes: readonly string[];
readonly enter?: BlockInputBehavior;
readonly lineBreak?: BlockInputBehavior;
readonly exit?: BlockInputBehavior;
}@quirekit/msfe-core整笔选区的不可变输入上下文;处理器只规划,不提交或修改 storage。
export interface BlockInputContext {
readonly state: EditorState;
readonly intent: BlockInputIntent;
readonly targets: readonly BlockInputTarget[];
}@quirekit/msfe-core一个选区端点及公共分派器为它解析出的当前语法所有者。
export interface BlockInputTarget {
readonly range: SelectionRange;
readonly position: number;
readonly node: SyntaxNode;
}@quirekit/msfe-coreEnter、Shift-Enter 和 Mod-Enter 对应的语义意图。
export type BlockInputIntent = "enter" | "lineBreak" | "exit";@quirekit/msfe-core一笔原子源码编辑、委托父级或回退原生键盘处理。
export type BlockInputResult = TransactionSpec | "parent" | "native";@quirekit/msfe-core参数 context:经过统一校验的完整选区输入。 返回:针对整笔动作的纯规划结果。
export type BlockInputHandler = (context: BlockInputContext) => BlockInputResult;@quirekit/msfe-core纯规划函数或固定归属决定;固定决定无需逐键调用函数。
export type BlockInputBehavior = BlockInputHandler | "parent" | "native";@quirekit/msfe-core解析输入归属,不触发解析、提交或扫描无关块。 参数 state:规范的不可变源码状态。 参数 intent:请求的键盘意图。 返回:完整选区的一笔编辑,或不产生部分修改的原生回退。
function planBlockInput(state: EditorState, intent: BlockInputIntent): TransactionSpec | null