From 255a011f0ecf004b31c59945b10154b10fac3af1 Mon Sep 17 00:00:00 2001 From: Daniel Colascione Date: Mon, 4 May 2015 11:46:12 -0700 Subject: [PATCH] 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. --- doc/lispref/positions.texi | 8 ++++++++ lisp/font-lock.el | 2 +- lisp/simple.el | 38 ++++++++++++++++++++++++++++++++++++++ src/editfns.c | 4 ++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/doc/lispref/positions.texi b/doc/lispref/positions.texi index fc47f1c7a78..e7c79d58241 100644 --- a/doc/lispref/positions.texi +++ b/doc/lispref/positions.texi @@ -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 diff --git a/lisp/font-lock.el b/lisp/font-lock.el index 96b290e34f4..b1455131114 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el @@ -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)) diff --git a/lisp/simple.el b/lisp/simple.el index 31efe3896d4..9f42f00b149 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -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. diff --git a/src/editfns.c b/src/editfns.c index dead48c1a62..1686fbf668b 100644 --- a/src/editfns.c +++ b/src/editfns.c @@ -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) { -- 2.39.2