Pregunta

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?

¿Fue útil?

Solución 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.

Otros consejos

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top