这是两个删除句子的命令(不保存到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)))))
当我运行第一个命令然后撤消它时,点会在正确的位置结束,而第二个命令则不是这样。为什么会出现这种差异?
答案 0 :(得分:2)
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
)逐步调试调试器。这将有助于您了解正在发生的事情。
答案 1 :(得分: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
中。只有在那之后旧点位置才会恢复。