emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[elpa] externals/compat 53c2dd04ec 3/4: compat-29: Add buffer-local-set-


From: ELPA Syncer
Subject: [elpa] externals/compat 53c2dd04ec 3/4: compat-29: Add buffer-local-set-state and buffer-local-restore-state
Date: Wed, 18 Jan 2023 02:57:32 -0500 (EST)

branch: externals/compat
commit 53c2dd04ec0034649466bdff3da3f0c6c2a3f26e
Author: Daniel Mendler <mail@daniel-mendler.de>
Commit: Daniel Mendler <mail@daniel-mendler.de>

    compat-29: Add buffer-local-set-state and buffer-local-restore-state
---
 NEWS.org        |  1 +
 compat-29.el    | 35 +++++++++++++++++++++++++++++++++++
 compat-tests.el | 18 ++++++++++++++++++
 compat.texi     | 12 ++++++++++++
 4 files changed, 66 insertions(+)

diff --git a/NEWS.org b/NEWS.org
index 985fb71100..d700de1f99 100644
--- a/NEWS.org
+++ b/NEWS.org
@@ -13,6 +13,7 @@
 - compat-29: Add ~list-of-strings-p~.
 - compat-29: Add ~delete-line~.
 - compat-29: Add ~with-narrowing~.
+- compat-29: Add ~buffer-local-set-state~ and ~buffer-local-restore-state~.
 
 * Release of "Compat" Version 29.1.2.0
 
diff --git a/compat-29.el b/compat-29.el
index 4010a9ee0f..ec5b81e2ad 100644
--- a/compat-29.el
+++ b/compat-29.el
@@ -171,6 +171,41 @@ This function does not move point.  Also see 
`line-end-position'."
 
 ;;;; Defined in subr.el
 
+(compat-defun buffer-local-restore-state (states)
+  "Restore values of buffer-local variables recorded in STATES.
+STATES should be an object returned by `buffer-local-set-state'."
+  (dolist (state states)
+    (if (cadr state)
+        (set (car state) (caddr state))
+      (kill-local-variable (car state)))))
+
+(compat-defun buffer-local-set-state--get (pairs)
+  "Internal helper function."
+  (let ((states nil))
+    (while pairs
+      (push (list (car pairs)
+                  (and (boundp (car pairs))
+                       (local-variable-p (car pairs)))
+                  (and (boundp (car pairs))
+                       (symbol-value (car pairs))))
+            states)
+      (setq pairs (cddr pairs)))
+    (nreverse states)))
+
+(compat-defmacro buffer-local-set-state (&rest pairs)
+  "Like `setq-local', but allow restoring the previous state of locals later.
+This macro returns an object that can be passed to `buffer-local-restore-state'
+in order to restore the state of the local variables set via this macro.
+
+\(fn [VARIABLE VALUE]...)"
+  (declare (debug setq))
+  (unless (zerop (mod (length pairs) 2))
+    (error "PAIRS must have an even number of variable/value members"))
+  `(prog1
+       (buffer-local-set-state--get ',pairs)
+     (,(if (fboundp 'compat--setq-local) 'compat--setq-local 'setq-local)
+      ,@pairs)))
+
 (compat-defun list-of-strings-p (object) ;; <compat-tests:lists-of-strings-p>
   "Return t if OBJECT is nil or a list of strings."
   (declare (pure t) (side-effect-free t))
diff --git a/compat-tests.el b/compat-tests.el
index 9b787db94b..9c8f4dd8ce 100644
--- a/compat-tests.el
+++ b/compat-tests.el
@@ -908,6 +908,24 @@
   (should-equal compat-tests--local-b 2)
   (should-equal compat-tests--local-c 3))
 
+(defvar compat-tests--global)
+(defvar compat-tests--local)
+(defvar compat-tests--unexist)
+(ert-deftest buffer-local-set-state ()
+  (setq compat-tests--global 1)
+  (with-temp-buffer
+    (setq-local compat-tests--local 2)
+    (let ((state (buffer-local-set-state compat-tests--global 10
+                                         compat-tests--local 20
+                                         compat-tests--unexist 30)))
+      (should (= compat-tests--global 10))
+      (should (= compat-tests--local 20))
+      (should (= compat-tests--unexist 30))
+      (buffer-local-restore-state state)
+      (should (= compat-tests--global 1))
+      (should (= compat-tests--local 2))
+      (should-not (boundp 'compat-tests--unexist)))))
+
 (ert-deftest gensym ()
   (let ((orig gensym-counter))
     (should (integerp gensym-counter))
diff --git a/compat.texi b/compat.texi
index 794e724057..9295956ff3 100644
--- a/compat.texi
+++ b/compat.texi
@@ -2012,6 +2012,18 @@ provided by Compat. Note that due to upstream changes, 
it might happen
 that there will be the need for changes, so use these functions with
 care.
 
+@c copied from lispref/modes.texi
+@findex buffer-local-restore-state
+@defmac buffer-local-set-state variable value...
+Minor modes often set buffer-local variables that affect some features
+in Emacs.  When a minor mode is switched off, the mode is expected to
+restore the previous state of these variables.  This convenience macro
+helps with doing that: It works much like @code{setq-local}, but
+returns an object that can be used to restore these values back to
+their previous values/states (using the companion function
+@code{buffer-local-restore-state}).
+@end defmac
+
 @c based on lisp/subr.el
 @defun delete-line
 Delete the current line.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]