尧图精选

Milkdown 历史记录插件 @milkdown/plugin-history 实战指南:撤销/重做、快捷键重映射与编程式命令调用

🕒 发布时间:2026/9/15 19:42:20 📁 来源:尧图网络
Milkdown 历史记录插件 milkdown/plugin-history 实战指南撤销/重做、快捷键重映射与编程式命令调用【免费下载链接】milkdown Plugin driven WYSIWYG markdown editor framework.项目地址: https://gitcode.com/GitHub_Trending/mi/milkdownmilkdown/plugin-history 是 Milkdown 编辑器框架内置的撤销Undo/ 重做Redo历史记录插件它基于 ProseMirror 的prosemirror-history模块为 WYSIWYG Markdown 编辑器提供开箱即用的操作历史能力。本指南以官方文档 docs/api/plugin-history.md 为主体结合仓库源码深入讲解插件的组成结构、快捷键重映射方式、编程式命令调用方法及底层实现原理读完即可在你的 Milkdown 编辑器中接入并定制完整的历史记录功能。插件是什么历史记录是富文本编辑器最基础、最不可或缺的能力之一用户每次输入、删除、格式化或执行命令都会改变文档状态历史记录允许用户通过Ctrl/⌘ Z撤销误操作通过Ctrl/⌘ Y或Shift Ctrl/⌘ Z重做。Milkdown 没有自行实现这套复杂的算法而是将prosemirror-history作为底层引擎packages/prose/src/history.ts 直接export * from prosemirror-history在其之上封装成符合 Milkdown 插件体系的模块。插件当前版本为7.22.1见 packages/plugins/plugin-history/package.json依赖milkdown/core、milkdown/ctx、milkdown/prose与milkdown/utils四个基础包。安装与快速开始在安装milkdown/plugin-history后通过Editor.make()的.use()链式调用接入即可无需任何额外配置import { Editor } from milkdown/kit/core import { history } from milkdown/kit/plugin/history import { commonmark } from milkdown/kit/preset/commonmark import { nord } from milkdown/theme-nord Editor.make().use(nord).use(commonmark).use(history).create()注意两个细节推荐从milkdown/kit聚合包导入。仓库中 packages/kit/src/plugin/history.ts 只有一行export * from milkdown/plugin-history即 kit 包负责统一转发让用户只需引入一个入口插件加载顺序不敏感history是独立模块不依赖 commonmark 等 preset但通常建议与 preset 一起使用保证对段落、标题、列表等内容的编辑操作都能被记录。插件的组成结构官方文档通过history、historyProviderConfig、historyProviderPlugin三个符号说明插件的组成。查看源码 packages/plugins/plugin-history/src/index.ts 可以确认history实际上是一个由四个子插件扁平化组合而成的插件数组export const history: MilkdownPlugin[] [ historyProviderConfig, historyProviderPlugin, historyKeymap, undoCommand, redoCommand, ].flat()每个子插件各司其职子插件类型职责historyProviderConfig$ctx声明历史插件的配置切片Slice承载可调参数historyProviderPlugin$prose将 ProseMirror 原生history插件挂载进 Milkdown 编辑器视图historyKeymap$useKeymap绑定默认的撤销/重做快捷键undoCommand/redoCommand$command注册可被编程式调用的撤销/重做命令下面逐一展开。historyProviderConfig可配置项historyProviderConfig是一个$ctx配置切片类型定义如下见 packages/plugins/plugin-history/src/index.tsexport const historyProviderConfig $ctx { depth?: number; newGroupDelay?: number }, historyProviderConfig ({}, historyProviderConfig)它暴露了两个可选参数直接透传给 ProseMirror 的history()配置depth历史记录栈最多保存的文档状态数量超过后最早的记录会被丢弃默认由prosemirror-history内部决定newGroupDelay将连续输入事件归并为同一历史分组的时间阈值毫秒。两次输入间隔小于该值会被视为同一步操作从而合并为一次撤销间隔更大则拆分为独立步骤。适当地调大该值可以让输入一句话后按一次撤销的体验更连贯。默认值传入了空对象{}即不覆盖 ProseMirror 的默认行为。historyProviderPlugin桥接 ProseMirrorhistoryProviderPlugin是一个$prose插件作用是把 ProseMirror 的历史插件实例注册进编辑器见 packages/plugins/plugin-history/src/index.tsexport const historyProviderPlugin $prose((ctx) prosemirrorHistory(ctx.get(historyProviderConfig.key)) )这里$prose是 Milkdown 提供的组合式 API用来将任意的 ProseMirror 插件接入编辑器状态机ctx.get(historyProviderConfig.key)则负责在插件初始化时读取用户通过配置切片设置的depth/newGroupDelay值。也就是说上层配置通过$ctx与$prose的联动最终成为 ProseMirror 历史插件的构造参数。快捷键与重映射插件默认绑定三组快捷键见 packages/plugins/plugin-history/src/index.tsexport const historyKeymap $useKeymap(historyKeymap, { Undo: { shortcuts: Mod-z, command: (ctx) { const commands ctx.get(commandsCtx) return () commands.call(undoCommand.key) }, }, Redo: { shortcuts: [Mod-y, Shift-Mod-z], command: (ctx) { const commands ctx.get(commandsCtx) return () commands.call(redoCommand.key) }, }, })UndoMod-zmacOS 上为⌘ ZWindows/Linux 上为Ctrl ZRedoMod-y与Shift-Mod-zmacOS 的⌘ Shift Z、Windows/Linux 的Ctrl Y与Ctrl Shift Z均可用。Mod是 ProseMirror 的修饰键占位符会根据运行平台自动解析为Cmd或Ctrl因此无需为不同系统分别写快捷键。重映射快捷键官方文档提供了通过historyKeymap.key重映射快捷键的完整示例import { history, historyKeymap } from milkdown/plugin-history Editor.make() .config((ctx) { ctx.set(historyKeymap.key, { // Remap to one shortcut. Undo: Mod-z, // Remap to multiple shortcuts. Redo: [Mod-y, Shift-Mod-z], }) }) .use(nord) .use(commonmark) .use(history) .create()这套机制的实现原理在$useKeymap组合式 API 中packages/utils/src/composable/composed/$use-keymap.ts$useKeymap(name, userKeymap)会把传入的快捷键配置写入一个名为historyKeymap的$ctx切片key即该切片的SliceType供ctx.set/ctx.get读写同时生成一个$shortcut插件在运行时ctx.get(keymapDef.key)读取用户的最新配置并把它与userKeymap中定义好的command配对展开成键名到命令的映射表重映射时只需提供shortcuts可传字符串或字符串数组与可选的prioritycommand无需重复声明因为它始终取自插件源码中的原始定义。priority可用于处理快捷键冲突当多个插件绑定同一快捷键时数值越大的键位越优先响应。编程式调用命令除了快捷键历史记录还可以通过命令Command体系编程式触发。文档中undoCommand与redoCommand对应的源码定义packages/plugins/plugin-history/src/index.tsexport const undoCommand $command(Undo, () () undo) export const redoCommand $command(Redo, () () redo)$command是 Milkdown 的命令工厂packages/utils/src/composable/$command.ts它创建一个以Undo/Redo为 key 的命令插件在CommandsReady时把命令注册进commandsCtx并暴露run()与key两个属性插件卸载时命令也会随之移除避免内存泄漏。文档给出的调用方式是与milkdown/plugin-utils的callCommand宏配合通过editor.action执行import { Undo, history } from milkdown/plugin-history import { callCommand } from milkdown/plugin-utils const editor await Editor.make().use(/* ... */).use(history).create() editor.action(callCommand(Undo))其中Undo即undoCommand.key命令 key。callCommand的实现非常精简packages/utils/src/macro/call-command.ts它返回一个接收ctx的函数内部调用ctx.get(commandsCtx).call(slice, payload)。因此editor.action(callCommand(Undo))等价于在编辑器上下文中执行commandsCtx.call(Undo)。同样地重做命令的完整写法为editor.action(callCommand(Redo))其中Redo是redoCommand.key。这一模式非常适合用于自定义工具条上的撤销/重做按钮在插件逻辑中基于业务条件如表单校验失败主动回退文档与其他命令组合成复合操作流。与编辑器其他机制的配合从源码可以进一步确认插件与 Milkdown 核心机制的协作关系命令路由快捷键回调通过ctx.get(commandsCtx)拿到命令上下文再commands.call(undoCommand.key)间接触发命令而不是直接调用 ProseMirror 的undo从而保证所有触发路径都经过统一的命令系统便于被监听、拦截或二次封装ProseMirror 桥接undo/redo本身来自prosemirror-history经 packages/prose/src/history.ts 转发由$prose插件的状态字段挂载到编辑器视图中历史记录与 Milkdown 的文档变更管线天然同步kit 聚合入口通过milkdown/kit/plugin/history导入时packages/kit/src/plugin/history.ts 会原样转发milkdown/plugin-history的全部导出因此文档示例中history、historyKeymap、Undo等符号均可从 kit 包获取。小结milkdown/plugin-history 用极小的 API 面一个history插件数组 一个可重映射的historyKeymap 两个可编程调用的命令完成了编辑器的撤销/重做闭环。接入只需.use(history)一行需要定制快捷键时用.config((ctx) ctx.set(historyKeymap.key, ...))需要程序化控制时用editor.action(callCommand(Undo))。其背后是 Milkdown 组合式插件体系$ctx/$prose/$command/$useKeymap与prosemirror-history的成熟实现结合值得作为学习 Milkdown 插件开发范式的入门案例。若需深入可继续阅读 packages/plugins/plugin-history/src/index.ts、packages/utils/src/composable/$command.ts 与 packages/utils/src/composable/composed/$use-keymap.ts 三份核心源码。【免费下载链接】milkdown Plugin driven WYSIWYG markdown editor framework.项目地址: https://gitcode.com/GitHub_Trending/mi/milkdown创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联 返回资讯列表 →