From f7497580ac2d135144aa3a08850cb9db5438a545 Mon Sep 17 00:00:00 2001 From: Eshel Yaron Date: Tue, 12 Dec 2023 14:17:33 +0100 Subject: [PATCH] New variable 'undo-inhibit-region'. This buffer-local variable allows Lisp code to tell the next 'undo' invocation to ignore an active region. * lisp/simple.el (undo-inhibit-region): New variable. (undo): Use it. * etc/NEWS: Announce it. * doc/lispref/text.texi (Undo): Mention it. --- doc/lispref/text.texi | 5 ++++- etc/NEWS | 9 +++++++++ lisp/simple.el | 23 ++++++++++++++++++++--- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi index 7ee2b06891d..9f9c7ed0783 100644 --- a/doc/lispref/text.texi +++ b/doc/lispref/text.texi @@ -1524,11 +1524,14 @@ This macro removes all the undo boundaries inserted during the execution of @var{body} so that it can be undone as a single step. @end defmac +@vindex undo-inhibit-region Some commands leave the region active after execution in such a way that it interferes with selective undo of that command. To make @code{undo} ignore the active region when invoked immediately after such a command, set the property @code{undo-inhibit-region} of the command's function -symbol to a non-@code{nil} value. @xref{Standard Properties}. +symbol to a non-@code{nil} value. @xref{Standard Properties}. You can +also set the buffer-local variable @code{undo-inhibit-region} from any +Lisp function to make the next @code{undo} ignore an active region. @node Maintaining Undo @section Maintaining Undo Lists diff --git a/etc/NEWS b/etc/NEWS index a4edd6f1891..93d8a70d55b 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1310,6 +1310,15 @@ from which you are switching. You can check for this variable in your 'read-buffer-function' to determine if the caller intends to switch to the buffer that this function reads. ++++ +** New buffer-local variable 'undo-inhibit-region'. +Lisp code can set this to non-nil to tell the next 'undo' command to +ignore an active region. This allows functions to select a region +without restricting a subsequent 'undo'. For commands that activate +the region and never want to restrict 'undo' to that region, it is +preferable to use the existing 'undo-inhibit-region' symbol property +instead of this variable. + ** New function 'merge-ordered-lists'. Mostly used internally to do a kind of topological sort of inheritance hierarchies. diff --git a/lisp/simple.el b/lisp/simple.el index ca1f326a81b..82fbfe05e1f 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -3438,6 +3438,20 @@ undo record: if we undo from 4, `pending-undo-list' will be at 3, "Within a run of consecutive undo commands, list remaining to be undone. If t, we undid all the way to the end of it.") +(defvar-local undo-inhibit-region nil + "Whether to inhibit the restriction of \\[undo] to the active region. + +If this is non-nil, the next invocation of \\[undo] operates on +the entire buffer even if the region is active. \\[undo] sets +this variable back to nil after consulting it. + +Functions that set the active region can use this variable to +have a subsequent \\[undo] undo other changes outside the region. + +For commands that set the active region and never want to +restrict \\[undo] to that region, it is preferable to use the +`undo-inhibit-region' symbol property instead of this variable.") + (defun undo--last-change-was-undo-p (undo-list) (while (and (consp undo-list) (eq (car undo-list) nil)) (setq undo-list (cdr undo-list))) @@ -3466,13 +3480,16 @@ as an argument limits undo to changes within the current region." (recent-auto-save-p))) ;; Allow certain commands to inhibit an immediately following ;; undo-in-region. - (inhibit-region (and (symbolp last-command) - (get last-command 'undo-inhibit-region))) + (inhibit-region (or undo-inhibit-region + (and (symbolp last-command) + (get last-command 'undo-inhibit-region)))) message) ;; If we get an error in undo-start, ;; the next command should not be a "consecutive undo". ;; So set `this-command' to something other than `undo'. - (setq this-command 'undo-start) + (setq this-command 'undo-start + ;; Restore region restrictions for subsequent invocations. + undo-inhibit-region nil) ;; Here we decide whether to break the undo chain. If the ;; previous command is `undo', we don't call `undo-start', i.e., ;; don't break the undo chain. -- 2.39.5