Recommand against save-window-excursion in Lisp manual.
authorChong Yidong <cyd@gnu.org>
Sun, 2 Sep 2012 04:47:28 +0000 (12:47 +0800)
committerChong Yidong <cyd@gnu.org>
Sun, 2 Sep 2012 04:47:28 +0000 (12:47 +0800)
* windows.texi (Window Configurations): Recommend against using
save-window-excursion.

* control.texi (Catch and Throw):
* positions.texi (Excursions): Don't mention it.

Fixes: debbugs:12075

doc/lispref/ChangeLog
doc/lispref/control.texi
doc/lispref/positions.texi
doc/lispref/windows.texi

index 30169d6..b0156e5 100644 (file)
@@ -1,3 +1,11 @@
+2012-09-02  Chong Yidong  <cyd@gnu.org>
+
+       * windows.texi (Window Configurations): Recommend against using
+       save-window-excursion (Bug#12075).
+
+       * control.texi (Catch and Throw):
+       * positions.texi (Excursions): Don't mention it.
+
 2012-09-01  Paul Eggert  <eggert@cs.ucla.edu>
 
        Better seed support for (random).
index 07d2d0d..25a7655 100644 (file)
@@ -556,16 +556,14 @@ the @code{catch} in @code{foo-outer} specifies the same symbol, so that
 @code{catch} in between).
 
   Executing @code{throw} exits all Lisp constructs up to the matching
-@code{catch}, including function calls.  When binding constructs such as
-@code{let} or function calls are exited in this way, the bindings are
-unbound, just as they are when these constructs exit normally
+@code{catch}, including function calls.  When binding constructs such
+as @code{let} or function calls are exited in this way, the bindings
+are unbound, just as they are when these constructs exit normally
 (@pxref{Local Variables}).  Likewise, @code{throw} restores the buffer
 and position saved by @code{save-excursion} (@pxref{Excursions}), and
-the narrowing status saved by @code{save-restriction} and the window
-selection saved by @code{save-window-excursion} (@pxref{Window
-Configurations}).  It also runs any cleanups established with the
-@code{unwind-protect} special form when it exits that form
-(@pxref{Cleanups}).
+the narrowing status saved by @code{save-restriction}.  It also runs
+any cleanups established with the @code{unwind-protect} special form
+when it exits that form (@pxref{Cleanups}).
 
   The @code{throw} need not appear lexically within the @code{catch}
 that it jumps to.  It can equally well be called from another function
index a59a99d..a0c6531 100644 (file)
@@ -850,9 +850,6 @@ after setting the desired current buffer, as in the following example:
 @cindex window excursions
   Likewise, @code{save-excursion} does not restore window-buffer
 correspondences altered by functions such as @code{switch-to-buffer}.
-One way to restore these correspondences, and the selected window, is to
-use @code{save-window-excursion} inside @code{save-excursion}
-(@pxref{Window Configurations}).
 
   @strong{Warning:} Ordinary insertion of text adjacent to the saved
 point value relocates the saved value, just as it relocates all
index ba2a944..5fe007b 100644 (file)
@@ -3153,42 +3153,21 @@ as @code{save-window-excursion}:
 @end defun
 
 @defmac save-window-excursion forms@dots{}
-This special form records the window configuration, executes @var{forms}
-in sequence, then restores the earlier window configuration.  The window
-configuration includes, for each window, the value of point and the
-portion of the buffer that is visible.  It also includes the choice of
-selected window.  However, it does not include the value of point in
-the current buffer; use @code{save-excursion} also, if you wish to
-preserve that.
-
-Don't use this construct when @code{save-selected-window} is sufficient.
-
-Exit from @code{save-window-excursion} always triggers execution of
-@code{window-size-change-functions}.  (It doesn't know how to tell
-whether the restored configuration actually differs from the one in
-effect at the end of the @var{forms}.)
-
-The return value is the value of the final form in @var{forms}.
-For example:
-
-@example
-@group
-(split-window)
-     @result{} #<window 25 on control.texi>
-@end group
-@group
-(setq w (selected-window))
-     @result{} #<window 19 on control.texi>
-@end group
-@group
-(save-window-excursion
-  (delete-other-windows w)
-  (switch-to-buffer "foo")
-  'do-something)
-     @result{} do-something
-     ;; @r{The screen is now split again.}
-@end group
-@end example
+This macro records the window configuration of the selected frame,
+executes @var{forms} in sequence, then restores the earlier window
+configuration.  The return value is the value of the final form in
+@var{forms}.
+
+Most Lisp code should not use this macro; @code{save-selected-window}
+is typically sufficient.  In particular, this macro cannot reliably
+prevent the code in @var{forms} from opening new windows, because new
+windows might be opened in other frames (@pxref{Choosing Window}), and
+@code{save-window-excursion} only saves and restores the window
+configuration on the current frame.
+
+Do not use this macro in @code{window-size-change-functions}; exiting
+the macro triggers execution of @code{window-size-change-functions},
+leading to an endless loop.
 @end defmac
 
 @defun window-configuration-p object
@@ -3424,11 +3403,11 @@ Creating or deleting windows counts as a size change, and therefore
 causes these functions to be called.  Changing the frame size also
 counts, because it changes the sizes of the existing windows.
 
-It is not a good idea to use @code{save-window-excursion} (@pxref{Window
-Configurations}) in these functions, because that always counts as a
-size change, and it would cause these functions to be called over and
-over.  In most cases, @code{save-selected-window} (@pxref{Selecting
-Windows}) is what you need here.
+You may use @code{save-selected-window} in these functions
+(@pxref{Selecting Windows}).  However, do not use
+@code{save-window-excursion} (@pxref{Window Configurations}); exiting
+that macro counts as a size change, which would cause these functions
+to be called over and over.
 @end defvar
 
 @defvar window-configuration-change-hook