3

这里有两个命令可以向前删除一个句子(不保存到 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)))))

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

4

2 回答 2

2

save-excursion仅保存(并尝试恢复)点、标记和当前缓冲区。这样做没有什么意义delete-region。用 C 编码,delete-region不跟踪任何东西,AFAIK。不知道如何undo处理它的影响。

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

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

于 2013-11-12T17:04:21.187 回答
1

该命令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

于 2013-11-12T17:33:40.930 回答