It is often useful to move point “temporarily” within a localized
portion of the program, or to switch buffers temporarily. This is
called an excursion, and it is done with the save-excursion
special form. This construct initially remembers the identity of the
current buffer, and its values of point and the mark, and restores them
after the completion of the excursion.
The forms for saving and restoring the configuration of windows are
described elsewhere (see Window Configurations, and see Frame Configurations). When only the identity of the current buffer needs
to be saved and restored, it is preferable to use
save-current-buffer instead.
The
save-excursionspecial form saves the identity of the current buffer and the values of point and the mark in it, evaluates body, and finally restores the buffer and its saved values of point and the mark. All three saved values are restored even in case of an abnormal exit viathrowor error (see Nonlocal Exits).The
save-excursionspecial form is the standard way to move point within one part of a program and avoid affecting the rest of the program. It is used more than 4000 times in the Lisp sources of Emacs.
save-excursiondoes not save the values of point and the mark for other buffers, so changes in other buffers remain in effect aftersave-excursionexits.Likewise,
save-excursiondoes not restore window-buffer correspondences altered by functions such asswitch-to-buffer. One way to restore these correspondences, and the selected window, is to usesave-window-excursioninsidesave-excursion(see Window Configurations).The value returned by
save-excursionis the result of the last form in body, ornilif no body forms were given.(save-excursion forms) == (let ((old-buf (current-buffer)) (old-pnt (point-marker)) (old-mark (copy-marker (mark-marker)))) (unwind-protect (progn forms) (set-buffer old-buf) (goto-char old-pnt) (set-marker (mark-marker) old-mark)))
Warning: Ordinary insertion of text adjacent to the saved
point value relocates the saved value, just as it relocates all markers.
More precisely, the saved value is a marker with insertion type
nil. See Marker Insertion Types. Therefore, when the saved
point value is restored, it normally comes before the inserted text.
Although save-excursion saves the location of the mark, it does
not prevent functions which modify the buffer from setting
deactivate-mark, and thus causing the deactivation of the mark
after the command finishes. See The Mark.