Add save-mark-and-excursion', which has the old save-excursion' behavior

* doc/lispref/positions.texi (Excursions): Document
`save-mark-and-excursion'.

* lisp/font-lock.el (font-lock-fontify-block): Use
`save-mark-and-excursion' instead of `save-excursion', restoring
Emacs 24 behavior.

* lisp/simple.el (save-mark-and-excursion--save)
(save-mark-and-excursion--restore): New functions.
(save-mark-and-excursion): New user macro.

* src/editfns.c (Fsave_excursion): Mention
`save-mark-and-excursion' in `save-excursion' documentation.
This commit is contained in:
Daniel Colascione 2015-05-04 11:46:12 -07:00
parent fe4e258b17
commit 255a011f0e
4 changed files with 51 additions and 1 deletions

View file

@ -888,6 +888,14 @@ type @code{nil}. @xref{Marker Insertion Types}. Therefore, when the
saved point value is restored, it normally comes before the inserted
text.
@defmac save-mark-and-excursion body@dots{}
@cindex mark excursion
@cindex point excursion
This macro is like @code{save-excursion}, but also saves and restores
the mark location and @code{mark-active}. This macro does what
@code{save-excursion} did before Emacs 25.1.
@end defmac
@node Narrowing
@section Narrowing
@cindex narrowing

View file

@ -1350,7 +1350,7 @@ delimit the region to fontify."
deactivate-mark)
;; Make sure we have the right `font-lock-keywords' etc.
(if (not font-lock-mode) (font-lock-set-defaults))
(save-excursion
(save-mark-and-excursion
(save-match-data
(condition-case error-data
(if (or arg (not font-lock-mark-block-function))

View file

@ -4870,6 +4870,44 @@ store it in a Lisp variable. Example:
(setq mark-active nil)
(set-marker (mark-marker) nil)))
(defun save-mark-and-excursion--save ()
(cons
(let ((mark (mark-marker)))
(and mark (marker-position mark) (copy-marker mark)))
mark-active))
(defun save-mark-and-excursion--restore (saved-mark-info)
(let ((saved-mark (car saved-mark-info))
(omark (marker-position (mark-marker)))
(nmark nil)
(saved-mark-active (cdr saved-mark-info)))
;; Mark marker
(if (null saved-mark)
(set-marker (mark-marker nil))
(setf nmark (marker-position saved-mark))
(set-marker (mark-marker) nmark)
(set-marker saved-mark nil))
;; Mark active
(let ((cur-mark-active mark-active))
(setf mark-active saved-mark-active)
;; If mark is active now, and either was not active or was at a
;; different place, run the activate hook.
(if saved-mark-active
(unless (eq omark nmark)
(run-hooks 'activate-mark-hook))
;; If mark has ceased to be active, run deactivate hook.
(when cur-mark-active
(run-hooks 'deactivate-mark-hook))))))
(defmacro save-mark-and-excursion (&rest body)
"Like `save-excursion', but also save and restore the mark state.
This macro does what `save-excursion' did before Emacs 25.1."
(let ((saved-marker-sym (make-symbol "saved-marker")))
`(let ((,saved-marker-sym (save-mark-and-excursion--save)))
(unwind-protect
(save-excursion ,@body)
(save-mark-and-excursion--restore ,saved-marker-sym)))))
(defcustom use-empty-active-region nil
"Whether \"region-aware\" commands should act on empty regions.
If nil, region-aware commands treat empty regions as inactive.

View file

@ -908,6 +908,10 @@ even in case of abnormal exit (throw or error).
If you only want to save the current buffer but not point,
then just use `save-current-buffer', or even `with-current-buffer'.
Before Emacs 25.1, `save-excursion' used to save the mark state.
To save the marker state as well as the point and buffer, use
`save-mark-and-excursion'.
usage: (save-excursion &rest BODY) */)
(Lisp_Object args)
{