如何在对 Emacs 进行“撤消”之后进行“重做”更改?

这篇文章 说“ Emacs 有 redo,因为您可以在撤消时反向执行,从而撤消撤消”。

这是什么意思? 一个用户如何重做 Emacs?

161859 次浏览

简短的版本:通过撤消撤消。如果你撤销,然后执行一个非编辑命令,如,那么下一次撤销将撤销撤销,导致重做。

长版:

您可以将撤消看作是对操作堆栈的操作。如果你在一系列撤销操作之后执行一些命令(甚至是一个导航命令,比如),所有的撤销操作都会被推入操作堆栈。因此,下一个undo命令将撤销上一个命令。假设你确实有一个这样的操作序列:

  1. 插入“foo”
  2. 插入“酒吧”
  3. 我喜欢垃圾邮件。

现在,撤销。它将撤销最后一个操作,结果是以下列表:

  1. 插入“foo”
  2. 插入“酒吧”

如果你在这一点上做了一些事情而不是撤销——比如,操作堆栈看起来像这样:

  1. 插入“foo”
  2. 插入“酒吧”
  3. 我喜欢垃圾邮件。
  4. 撤销插入“我爱垃圾邮件”

当你撤消时,首先要撤消的是撤消。导致您的原始堆栈(和文档状态):

  1. 插入“foo”
  2. 插入“酒吧”
  3. 我喜欢垃圾邮件。

如果您执行一个修改命令来打破undo序列,则该命令被添加在undo之后,因此是之后要撤消的第一件事。假设你在“bar”上倒空,而不是击中。那么你就有了

  1. 插入“foo”
  2. 插入“酒吧”
  3. 我喜欢垃圾邮件。
  4. 撤销插入“我爱垃圾邮件”
  5. 删除“酒吧”

这种添加/重新添加会无限地发生。它需要一点时间来适应,但它确实为Emacs提供了高度灵活和强大的撤消/重做机制。

撤销:C _

在撤销之后重做:c gC _

C _上键入多次以重做 C-_所撤消的内容 要多次重做emacs命令,请执行您的命令,然后键入cxz,然后在z键上键入多次以重复该命令(当您想多次执行一个宏时很有趣)

我发现redo.el非常方便用于执行“正常的”撤销/重做,我通常将其绑定到C-S-z,并将其绑定到C-z,如下所示:

(when (require 'redo nil 'noerror)
(global-set-key (kbd "C-S-z") 'redo))


(global-set-key (kbd "C-z") 'undo)

只需下载文件,把它放在你的lisp路径和粘贴上面的.emacs

对于那些想要拥有更常见的撤消/重做功能的人,有人编写了undo-tree.el。它提供了非emacs撤消的外观和感觉,但提供了对撤消历史的整个“树”的访问。

我喜欢Emacs的内置撤销系统,但发现这个包非常直观。

以下是该文件本身的评论:

Emacs有一个强大的撤销系统。 不像标准的撤销/重做系统 在大多数软件中,它允许您这样做 恢复任何缓冲区的过去状态 (而标准的撤销/重做系统 能像你一样尽快失去过去的状态吗 重做)。然而,这种力量来自于一个 价格:很多人发现Emacs的撤销 系统混乱,难以使用, 生成了许多包 把它换成没那么强大的但是 更直观的撤销/重做系统

两者的数据丢失与标准 撤消/重做,以及Emacs的混乱 撤销,源于试图治疗撤销 历史是一个线性序列 的变化。它不是。的 ' undo-tree-mode' 包替换Emacs的撤销系统 用一个处理撤销历史记录的系统 就像它本身一样:一个分支的树 的变化。这个简单的想法允许 更直观的行为 标准的撤销/重做系统 再加上永不的力量 失去任何历史。增加的一面 好处是,撤销历史可以在一些 更有效地储存案件, 允许更多的变化累积 在Emacs开始丢弃之前 历史。< / p >

  • 撤销一次:C-/
  • 要撤消两次:C-/ C-/
  • 重做一次,在撤消后立即:C-g C-/
  • 要在撤消后立即重做两次:C-g C-/ C-/。注意C-g不是重复的。
  • 撤销立即再一次,一次:C-g C-/
  • 再次立即撤销,两次:C-g C-/ C-/
  • 再次重做,相同的…

如果你在上次执行undo命令后按下了任何键(无论是键入字符还是只是移动光标),那么在下一次执行undo/redo之前就不需要键入C-gC-g只是一个安全的键,它自己不做任何事情,但作为一个非撤销键来表示撤消序列的结束。按另一个命令,如C-f也可以工作;它只是将光标从你的位置移动。

如果你在无意中按了C-g或其他命令,并且你现在正在错误的方向上撤销,只需按C-g来再次反转你的方向。在你到达你想要的undos之前,你将不得不通过你的意外redo和undo来撤消所有的方法,但如果你只是继续敲击C-/,你最终会到达你想要的状态。事实上,如果你按一次C-g,然后按C-/足够多次,缓冲区曾经处于的每个状态都是可以到达的。

除了C-/undo的可选快捷键有C-_C-x uM-x undo

有关Emacs撤消系统的更多详细信息,请参阅Emacs手册中的撤销

当心重做undo-tree怪癖!

许多流行的“入门套件”(prelude, purcell, spacemacs)都捆绑了撤销树。大多数(全部?)甚至自动启用它。如前所述,撤销树是可视化和遍历撤销/重做树的方便方法。Prelude甚至给了它一个关键和弦(uu),还有C-x u

问题是:undo-tree似乎破坏了Emacs默认的和众所周知的绑定redo: C-g C-/

相反,你可以使用这些对称键来撤销/重做:

C-/     undo
C-S-/   redo

这些是有用的,因为有时你想快速重做而不打开可视化器。

如果您需要重做上次的操作,请执行以下操作。

  1. ESC
  2. 执行另一次撤销(C + /)

默认情况下,Emacs中的重做需要按C-g,然后撤销。

但是也可以使用Emacs内置的undo来实现重做命令。

undo-fu包使用Emacs内置的撤销功能来公开撤销和重做。


编辑,撤销fu现在已经集成到邪恶模式(如果你是一个邪恶模式的用户)。

例子:

(use-package undo-fu)
(use-package evil
:init
(setq evil-undo-system 'undo-fu))

Emacs 28 添加重做命令(称为undo-redo)。

如果您想要更典型的撤消/重做,可以使用以下命令。

(global-set-key (kbd "C-z") 'undo-only)
(global-set-key (kbd "C-S-z") 'undo-redo)

要访问此功能(也可以使用非线性历史,请参阅undo-fu,它是在undo中内置的emacs上的瘦包装器)。

厄运Emacs用户,我希望你已经滚动到这里或在页面上搜索“末日”…

  • Doom Emacs打破香草Emacs重做快捷方式: C-g C-/ C-/ C-/等(或C-g C-_ C-_ C-_等) ...而不是一直撤销.
  • Doom Emacs 打破了在其他答案中提到的撤消树重做快捷方式,因为它对spacemacs等有用: __abc0(又名__abc1) …而不是抛出错误"C-?

你需要的是:

  • 在邪恶模式(C-z切换进入和退出邪恶模式)(在邪恶模式应该看到蓝色光标,而不是橙色光标)和
  • 处于“命令模式”,也就是“正常模式”(与“插入模式”相反)(Esc切换到命令模式)(应该看到块游标,而不是行游标),然后它是
  • u用于撤销
  • C-r for redo

在末日emacs,
Ctrl + Shift + -来撤销
Alt + Shift + -重做