ctrl+z一次撤销多步


遇到的问题

obsidian的撤销功能不是单步撤销,是按时间来的,自动撤销到几秒前,导致使用Ctrl+z撤销时,会连撤多步。这和其他任何软件(如:浏览器)的撤销逻辑都不一样,很别扭。

我在设置中没有找到如何把它改成单步撤销。

复现步骤

比如键入数字时,输入"12345",点一次ctrl+z,应该会撤销为"1234", 实际都会被撤销。

比如粘贴图片时,连续粘贴两次,点一次ctrl+z,粘贴的两张图片都会被撤销。

所有操作都会这样。

环境

软件版本:August 12, 2026 1.13.7 Desktop

快捷键:未绑定ctrl+z。

插件:仅包括核心插件。

操作系统版本:Microsoft Windows 10、Microsoft Windows 11。

但是这个问题好多年一直都在,甚至可以被称为一个特性,但使用时候就极其不方便。

已尝试的解决方案

增加打字时候的间隔:键入数字时,输入"12345"时,输入频率改成一秒一个,点一次ctrl+z会撤销一个数字。撤销时不会连撤多步。

但是我打字时候是不可能慢到一秒打一个

备注

如果这个是一个改不了的"特性",是否应该提一个issue给官方修复?。

这是CodeMirror编辑器本身的撤销历史分组机制,不是Obsidian特有的bug——凡是用CodeMirror 6的产品应该都是这个行为,比如维基百科(MediaWiki)的源代码编辑器、Replit的在线IDE等。

技术上,CodeMirror的history()扩展有一个newGroupDelay参数,默认值是500ms。判断逻辑大致是:如果这次修改距离上一次修改的时间间隔小于 newGroupDelay,就会被合并进同一个撤销步骤。这就是为什么正常速度打字时Ctrl+Z会一次撤销一大段,而你测试的"每秒一个字符"能拆开撤销——因为间隔超过了500ms这个阈值。

调整方面,简单搜了一下没找到现成的插件能改这个设置。理论上可以自己写一个很小的插件,用history({ newGroupDelay: 一个更小的值 })重新注册这个扩展来覆盖默认的500ms,但需要写代码,没有现成的开关。

好的,感谢回复,我会用这种方法试一下的。

1 个赞

充一点:我实际测试了一下用 QuickAdd 的启动宏(Run on startup)来覆盖 newGroupDelay,思路是启动时通过 registerEditorExtension 注册一个新的 history() 扩展。但 QuickAdd 的 User Script 是未打包的原生 JS,没法 require('@codemirror/commands') 这类包——Obsidian 的插件都是在构建时把这些库直接打包进 main.js,运行时是单独 require 不到的。所以这个思路在 QuickAdd 里走不通,还是得写一个真正打包过的插件。