`save-excursion' does not save&restore the mark any more
* src/editfns.c (save_excursion_save): Don't save the mark. (save_excursion_restore): Don't restore the mark. (Fsave_excursion): Fix docstring accordingly. * doc/lispintro/emacs-lisp-intro.texi: * doc/lispref/positions.texi (Excursions, Narrowing): `save-excursion' does not save&restore the mark any more.
This commit is contained in:
parent
76040ddd8a
commit
599ca626d7
7 changed files with 55 additions and 81 deletions
|
@ -1,3 +1,7 @@
|
|||
2015-03-25 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* emacs-lisp-intro.texi: `save-excursion' doesn't save&restore the mark.
|
||||
|
||||
2014-12-31 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Less 'make' chatter for Emacs doc
|
||||
|
|
|
@ -352,7 +352,7 @@ How To Write Function Definitions
|
|||
* if:: What if?
|
||||
* else:: If--then--else expressions.
|
||||
* Truth & Falsehood:: What Lisp considers false and true.
|
||||
* save-excursion:: Keeping track of point, mark, and buffer.
|
||||
* save-excursion:: Keeping track of point and buffer.
|
||||
* Review::
|
||||
* defun Exercises::
|
||||
|
||||
|
@ -2966,7 +2966,7 @@ symbol refers to it.)
|
|||
* if:: What if?
|
||||
* else:: If--then--else expressions.
|
||||
* Truth & Falsehood:: What Lisp considers false and true.
|
||||
* save-excursion:: Keeping track of point, mark, and buffer.
|
||||
* save-excursion:: Keeping track of point and buffer.
|
||||
* Review::
|
||||
* defun Exercises::
|
||||
@end menu
|
||||
|
@ -4159,11 +4159,11 @@ The @code{save-excursion} function is the third and final special form
|
|||
that we will discuss in this chapter.
|
||||
|
||||
In Emacs Lisp programs used for editing, the @code{save-excursion}
|
||||
function is very common. It saves the location of point and mark,
|
||||
executes the body of the function, and then restores point and mark to
|
||||
their previous positions if their locations were changed. Its primary
|
||||
function is very common. It saves the location of point,
|
||||
executes the body of the function, and then restores point to
|
||||
its previous position if its location was changed. Its primary
|
||||
purpose is to keep the user from being surprised and disturbed by
|
||||
unexpected movement of point or mark.
|
||||
unexpected movement of point.
|
||||
|
||||
@menu
|
||||
* Point and mark:: A review of various locations.
|
||||
|
@ -4201,7 +4201,7 @@ region}. Numerous commands work on the region, including
|
|||
@code{print-region}.
|
||||
|
||||
The @code{save-excursion} special form saves the locations of point and
|
||||
mark and restores those positions after the code within the body of the
|
||||
restores this position after the code within the body of the
|
||||
special form is evaluated by the Lisp interpreter. Thus, if point were
|
||||
in the beginning of a piece of text and some code moved point to the end
|
||||
of the buffer, the @code{save-excursion} would put point back to where
|
||||
|
@ -4212,16 +4212,16 @@ In Emacs, a function frequently moves point as part of its internal
|
|||
workings even though a user would not expect this. For example,
|
||||
@code{count-lines-region} moves point. To prevent the user from being
|
||||
bothered by jumps that are both unexpected and (from the user's point of
|
||||
view) unnecessary, @code{save-excursion} is often used to keep point and
|
||||
mark in the location expected by the user. The use of
|
||||
view) unnecessary, @code{save-excursion} is often used to keep point in
|
||||
the location expected by the user. The use of
|
||||
@code{save-excursion} is good housekeeping.
|
||||
|
||||
To make sure the house stays clean, @code{save-excursion} restores the
|
||||
values of point and mark even if something goes wrong in the code inside
|
||||
value of point even if something goes wrong in the code inside
|
||||
of it (or, to be more precise and to use the proper jargon, ``in case of
|
||||
abnormal exit''). This feature is very helpful.
|
||||
|
||||
In addition to recording the values of point and mark,
|
||||
In addition to recording the value of point,
|
||||
@code{save-excursion} keeps track of the current buffer, and restores
|
||||
it, too. This means you can write code that will change the buffer and
|
||||
have @code{save-excursion} switch you back to the original buffer.
|
||||
|
@ -4386,9 +4386,9 @@ For example,
|
|||
@end smallexample
|
||||
|
||||
@item save-excursion
|
||||
Record the values of point and mark and the current buffer before
|
||||
evaluating the body of this special form. Restore the values of point
|
||||
and mark and buffer afterward.
|
||||
Record the values of point and the current buffer before
|
||||
evaluating the body of this special form. Restore the value of point and
|
||||
buffer afterward.
|
||||
|
||||
@need 1250
|
||||
For example,
|
||||
|
@ -5201,8 +5201,8 @@ of the two-element list, @code{(oldbuf (current-buffer))}.
|
|||
The body of the @code{let} expression in @code{append-to-buffer}
|
||||
consists of a @code{save-excursion} expression.
|
||||
|
||||
The @code{save-excursion} function saves the locations of point and
|
||||
mark, and restores them to those positions after the expressions in the
|
||||
The @code{save-excursion} function saves the location of point, and restores it
|
||||
to that position after the expressions in the
|
||||
body of the @code{save-excursion} complete execution. In addition,
|
||||
@code{save-excursion} keeps track of the original buffer, and
|
||||
restores it. This is how @code{save-excursion} is used in
|
||||
|
@ -5390,7 +5390,7 @@ Conventionally bound to @kbd{M-.} (that's a period following the
|
|||
@key{META} key).
|
||||
|
||||
@item save-excursion
|
||||
Save the location of point and mark and restore their values after the
|
||||
Save the location of point and restore its value after the
|
||||
arguments to @code{save-excursion} have been evaluated. Also, remember
|
||||
the current buffer and return to it.
|
||||
|
||||
|
@ -5896,7 +5896,7 @@ the value of point, which will be at the end of the inserted text, is
|
|||
recorded in the variable @code{newmark}.
|
||||
|
||||
After the body of the outer @code{save-excursion} is evaluated, point
|
||||
and mark are relocated to their original places.
|
||||
is relocated to its original place.
|
||||
|
||||
However, it is convenient to locate a mark at the end of the newly
|
||||
inserted text and locate point at its beginning. The @code{newmark}
|
||||
|
@ -6685,8 +6685,8 @@ restored just before the completion of the function by the
|
|||
@code{save-restriction} special form.
|
||||
|
||||
The call to @code{widen} is followed by @code{save-excursion}, which
|
||||
saves the location of the cursor (i.e., of point) and of the mark, and
|
||||
restores them after the code in the body of the @code{save-excursion}
|
||||
saves the location of the cursor (i.e., of point), and
|
||||
restores it after the code in the body of the @code{save-excursion}
|
||||
uses the @code{beginning-of-line} function to move point.
|
||||
|
||||
(Note that the @code{(widen)} expression comes between the
|
||||
|
@ -6757,8 +6757,8 @@ it, and @code{count-lines} counts only the lines @emph{before} the
|
|||
current line.
|
||||
|
||||
After @code{count-lines} has done its job, and the message has been
|
||||
printed in the echo area, the @code{save-excursion} restores point and
|
||||
mark to their original positions; and @code{save-restriction} restores
|
||||
printed in the echo area, the @code{save-excursion} restores point to
|
||||
its original position; and @code{save-restriction} restores
|
||||
the original narrowing, if any.
|
||||
|
||||
@node narrow Exercise
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2015-03-25 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* positions.texi (Excursions, Narrowing): `save-excursion' does not
|
||||
save&restore the mark any more.
|
||||
|
||||
2015-03-24 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
* numbers.texi (Float Basics): Improve ldexp documentation.
|
||||
|
|
|
@ -825,8 +825,8 @@ is zero or less.
|
|||
It is often useful to move point ``temporarily'' within a localized
|
||||
portion of the program. This is called an @dfn{excursion}, and it is
|
||||
done with the @code{save-excursion} special form. This construct
|
||||
remembers the initial identity of the current buffer, and its values
|
||||
of point and the mark, and restores them after the excursion
|
||||
remembers the initial identity of the current buffer, and its value
|
||||
of point, and restores them after the excursion
|
||||
completes. It is the standard way to move point within one part of a
|
||||
program and avoid affecting the rest of the program, and is used
|
||||
thousands of times in the Lisp sources of Emacs.
|
||||
|
@ -841,18 +841,18 @@ Configurations} and in @ref{Frame Configurations}. @c frameset?
|
|||
@cindex mark excursion
|
||||
@cindex point excursion
|
||||
This special form saves the identity of the current buffer and the
|
||||
values of point and the mark in it, evaluates @var{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 via
|
||||
value of point in it, evaluates @var{body}, and finally
|
||||
restores the buffer and its saved value of point. both saved values are
|
||||
restored even in case of an abnormal exit via
|
||||
@code{throw} or error (@pxref{Nonlocal Exits}).
|
||||
|
||||
The value returned by @code{save-excursion} is the result of the last
|
||||
form in @var{body}, or @code{nil} if no body forms were given.
|
||||
@end defspec
|
||||
|
||||
Because @code{save-excursion} only saves point and mark for the
|
||||
Because @code{save-excursion} only saves point for the
|
||||
buffer that was current at the start of the excursion, any changes
|
||||
made to point and/or mark in other buffers, during the excursion, will
|
||||
made to point in other buffers, during the excursion, will
|
||||
remain in effect afterward. This frequently leads to unintended
|
||||
consequences, so the byte compiler warns if you call @code{set-buffer}
|
||||
during an excursion:
|
||||
|
@ -888,11 +888,6 @@ type @code{nil}. @xref{Marker Insertion Types}. Therefore, when the
|
|||
saved point value is restored, it normally comes before the inserted
|
||||
text.
|
||||
|
||||
Although @code{save-excursion} saves the location of the mark, it does
|
||||
not prevent functions which modify the buffer from setting
|
||||
@code{deactivate-mark}, and thus causing the deactivation of the mark
|
||||
after the command finishes. @xref{The Mark}.
|
||||
|
||||
@node Narrowing
|
||||
@section Narrowing
|
||||
@cindex narrowing
|
||||
|
@ -980,7 +975,7 @@ restores the restrictions on the original buffer (the buffer whose
|
|||
restrictions it saved from), but it does not restore the identity of the
|
||||
current buffer.
|
||||
|
||||
@code{save-restriction} does @emph{not} restore point and the mark; use
|
||||
@code{save-restriction} does @emph{not} restore point; use
|
||||
@code{save-excursion} for that. If you use both @code{save-restriction}
|
||||
and @code{save-excursion} together, @code{save-excursion} should come
|
||||
first (on the outside). Otherwise, the old point value would be
|
||||
|
|
2
etc/NEWS
2
etc/NEWS
|
@ -617,6 +617,8 @@ a typographically-correct documents.
|
|||
|
||||
* Incompatible Lisp Changes in Emacs 25.1
|
||||
|
||||
** `save-excursion' does not save&restore the mark any more.
|
||||
|
||||
** read-buffer-function can now be called with a 4th argument (`predicate').
|
||||
|
||||
** completion-table-dynamic stays in the minibuffer.
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2015-03-25 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
* editfns.c (save_excursion_save): Don't save the mark.
|
||||
(save_excursion_restore): Don't restore the mark.
|
||||
(Fsave_excursion): Fix docstring accordingly.
|
||||
|
||||
2015-03-24 Paul Eggert <eggert@cs.ucla.edu>
|
||||
|
||||
Fix minor ldexp issues
|
||||
|
|
|
@ -849,14 +849,11 @@ save_excursion_save (void)
|
|||
{
|
||||
return make_save_obj_obj_obj_obj
|
||||
(Fpoint_marker (),
|
||||
/* Do not copy the mark if it points to nowhere. */
|
||||
(XMARKER (BVAR (current_buffer, mark))->buffer
|
||||
? Fcopy_marker (BVAR (current_buffer, mark), Qnil)
|
||||
: Qnil),
|
||||
Qnil,
|
||||
/* Selected window if current buffer is shown in it, nil otherwise. */
|
||||
(EQ (XWINDOW (selected_window)->contents, Fcurrent_buffer ())
|
||||
? selected_window : Qnil),
|
||||
BVAR (current_buffer, mark_active));
|
||||
Qnil);
|
||||
}
|
||||
|
||||
/* Restore saved buffer before leaving `save-excursion' special form. */
|
||||
|
@ -864,8 +861,8 @@ save_excursion_save (void)
|
|||
void
|
||||
save_excursion_restore (Lisp_Object info)
|
||||
{
|
||||
Lisp_Object tem, tem1, omark, nmark;
|
||||
struct gcpro gcpro1, gcpro2, gcpro3;
|
||||
Lisp_Object tem, tem1;
|
||||
struct gcpro gcpro1;
|
||||
|
||||
tem = Fmarker_buffer (XSAVE_OBJECT (info, 0));
|
||||
/* If we're unwinding to top level, saved buffer may be deleted. This
|
||||
|
@ -873,8 +870,7 @@ save_excursion_restore (Lisp_Object info)
|
|||
if (NILP (tem))
|
||||
goto out;
|
||||
|
||||
omark = nmark = Qnil;
|
||||
GCPRO3 (info, omark, nmark);
|
||||
GCPRO1 (info);
|
||||
|
||||
Fset_buffer (tem);
|
||||
|
||||
|
@ -883,34 +879,6 @@ save_excursion_restore (Lisp_Object info)
|
|||
Fgoto_char (tem);
|
||||
unchain_marker (XMARKER (tem));
|
||||
|
||||
/* Mark marker. */
|
||||
tem = XSAVE_OBJECT (info, 1);
|
||||
omark = Fmarker_position (BVAR (current_buffer, mark));
|
||||
if (NILP (tem))
|
||||
unchain_marker (XMARKER (BVAR (current_buffer, mark)));
|
||||
else
|
||||
{
|
||||
Fset_marker (BVAR (current_buffer, mark), tem, Fcurrent_buffer ());
|
||||
nmark = Fmarker_position (tem);
|
||||
unchain_marker (XMARKER (tem));
|
||||
}
|
||||
|
||||
/* Mark active. */
|
||||
tem = XSAVE_OBJECT (info, 3);
|
||||
tem1 = BVAR (current_buffer, mark_active);
|
||||
bset_mark_active (current_buffer, tem);
|
||||
|
||||
/* If mark is active now, and either was not active
|
||||
or was at a different place, run the activate hook. */
|
||||
if (! NILP (tem))
|
||||
{
|
||||
if (! EQ (omark, nmark))
|
||||
run_hook (intern ("activate-mark-hook"));
|
||||
}
|
||||
/* If mark has ceased to be active, run deactivate hook. */
|
||||
else if (! NILP (tem1))
|
||||
run_hook (intern ("deactivate-mark-hook"));
|
||||
|
||||
/* If buffer was visible in a window, and a different window was
|
||||
selected, and the old selected window is still showing this
|
||||
buffer, restore point in that window. */
|
||||
|
@ -932,18 +900,12 @@ save_excursion_restore (Lisp_Object info)
|
|||
}
|
||||
|
||||
DEFUN ("save-excursion", Fsave_excursion, Ssave_excursion, 0, UNEVALLED, 0,
|
||||
doc: /* Save point, mark, and current buffer; execute BODY; restore those things.
|
||||
doc: /* Save point, and current buffer; execute BODY; restore those things.
|
||||
Executes BODY just like `progn'.
|
||||
The values of point, mark and the current buffer are restored
|
||||
The values of point and the current buffer are restored
|
||||
even in case of abnormal exit (throw or error).
|
||||
The state of activation of the mark is also restored.
|
||||
|
||||
This construct does not save `deactivate-mark', and therefore
|
||||
functions that change the buffer will still cause deactivation
|
||||
of the mark at the end of the command. To prevent that, bind
|
||||
`deactivate-mark' with `let'.
|
||||
|
||||
If you only want to save the current buffer but not point nor mark,
|
||||
If you only want to save the current buffer but not point,
|
||||
then just use `save-current-buffer', or even `with-current-buffer'.
|
||||
|
||||
usage: (save-excursion &rest BODY) */)
|
||||
|
|
Loading…
Add table
Reference in a new issue