質問

Here are two commands to delete a sentence forward (without saving to the kill ring). The first is based on an example from EmacsWiki Elisp Cookbook, and the latter is like the former except that the call to save-excursion is in a different place.

;; 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)))))

When I run the first command and then undo it, point ends up in the right place, and that's not the case with the second command. Why does this difference happen?

役に立ちましたか?

解決 2

The command delete-region records the point position at the time when the text was deleted in buffer-undo-list (see help for buffer-undo-list).

In my-test-1 the construct (save-excursion (forward-sentence 1) (point)) just returns the end of sentence position but does not move point in the scope of the delete-region command.

In my-test-2 the point is moved to the end of sentence when deletion takes place. So, the end of sentence position is saved in buffer-undo-list. Only after that the old point position is restored.

他のヒント

save-excursion saves (and tries to restore) only point, mark, and which buffer is current. There is little sense in doing this around delete-region. Coded in C, delete-region does not keep track of anything, AFAIK. Dunno just how undo handles its effects.

A general rule of thumb is to use save-excursion as locally as possible, to do what you need done. In this case, you only need save-excursion to hide the effects of forward-sentence, not the effects of delete-region.

This is probably only a partial explanation. To see a bit more, you can do M-x debug-on-entry my-test-N and step through the debugger using d (and c). That will help you understand just what is going on.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top