撤销重做系统的设计与实现
概述
撤销重做是代码编辑器的核心功能之一。本文介绍 codes.js.cn 中撤销重做系统的设计与实现方案。
命令模式
我们采用命令模式来实现撤销重做功能。每一次编辑操作都被封装为一个命令对象。
class InsertCommand {
constructor(editor, text, position) {
this.editor = editor;
this.text = text;
this.position = position;
}
execute() {
this.editor.insert(this.text, this.position);
}
undo() {
this.editor.delete(this.position, this.text.length);
}
}
版本树结构
与传统的线性撤销栈不同,我们使用版本树来支持分支撤销。这对于协作编辑场景尤为重要。
- 每个节点代表一个编辑状态
- 节点可以有多 个子节点(分支)
- 新编辑创建新分支,而非覆盖
内存管理
- 限制最大历史记录数量(默认 1000 条)
- 定期压缩旧版本,节省内存
- 大文件操作使用增量存储
协作场景
在多人协作场景下,版本树可以有效处理并发编辑产生的冲突问题。每个用户的编辑历史独立维护,合并时通过 CRDT 算法同步。