【问题标题】:Interaction between undo, save-excursion, delete-regionundo、save-excursion、delete-region 之间的交互
【发布时间】:2013-11-24 22:10:06
【问题描述】:

这里有两个命令可以向前删除一个句子(不保存到 kill ring)。第一个基于 EmacsWiki Elisp Cookbook 中的示例,后者与前者类似,只是调用 save-excursion 的位置不同。

;; good with undo
(defun my-test-1 ()
  (interactive)
  (delete-region (point)
                 (save-excursion
                   (forward-sentence 1)
                   (point))))

;; bad with undo
(defun my-test-2 ()
  (interactive)
  (save-excursion
    (delete-region (point)
                   (progn
                     (forward-sentence 1)
                     (point)))))

当我运行第一个命令然后撤消它时,point 会出现在正确的位置,而第二个命令则不是这样。为什么会出现这种差异?

【问题讨论】:

    标签: emacs elisp undo


    【解决方案1】:

    save-excursion 仅保存(并尝试恢复)点、标记和当前缓冲区。在delete-region 周围这样做几乎没有意义。用 C 编码,delete-region 不跟踪任何东西,AFAIK。不知道undo 是如何处理其效果的。

    一般的经验法则是尽可能在本地使用save-excursion 来做您需要做的事情。在这种情况下,您只需要save-excursion 隐藏forward-sentence 的效果,而不是delete-region 的效果。

    这可能只是部分解释。要查看更多信息,您可以执行M-x debug-on-entry my-test-N 并使用d(和c)逐步调试调试器。这将帮助您了解正在发生的事情。

    【讨论】:

      【解决方案2】:

      命令delete-region记录buffer-undo-list中删除文本时的点位置(见buffer-undo-list的帮助)。

      my-test-1 中,构造(save-excursion (forward-sentence 1) (point)) 只返回句末位置,但不移动delete-region 命令范围内的点。

      my-test-2 中,当删除发生时,该点被移动到句子的末尾。所以,句末位置保存在buffer-undo-list中。只有在那之后,旧的点位置才会恢复。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-01-12
        • 1970-01-01
        • 2022-12-01
        • 2018-06-03
        • 2014-07-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多