]> git.bundesbrandschatzamt.de Git - emacsconfig.git/commitdiff
add persist
authorAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Sun, 22 Dec 2024 12:47:56 +0000 (13:47 +0100)
committerAndreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
Sun, 22 Dec 2024 12:54:19 +0000 (13:54 +0100)
Signed-off-by: Andreas Gerler <baronNOSPAMbundesbrandschatzamt.de>
elpa/persist-0.6.1.signed [new file with mode: 0644]
elpa/persist-0.6.1/.elpaignore [new file with mode: 0644]
elpa/persist-0.6.1/persist-autoloads.el [new file with mode: 0644]
elpa/persist-0.6.1/persist-pkg.el [new file with mode: 0644]
elpa/persist-0.6.1/persist.el [new file with mode: 0644]
elpa/persist-0.6.1/persist.texi [new file with mode: 0644]
elpa/persist-0.6.1/test/persist-tests.el [new file with mode: 0644]

diff --git a/elpa/persist-0.6.1.signed b/elpa/persist-0.6.1.signed
new file mode 100644 (file)
index 0000000..23cbb05
--- /dev/null
@@ -0,0 +1 @@
+Good signature from 645357D2883A0966 GNU ELPA Signing Agent (2023) <elpasignNOSPAMelpa.gnu.org> (trust undefined) created at 2024-06-15T23:10:02+0200 using EDDSA
\ No newline at end of file
diff --git a/elpa/persist-0.6.1/.elpaignore b/elpa/persist-0.6.1/.elpaignore
new file mode 100644 (file)
index 0000000..dfdac46
--- /dev/null
@@ -0,0 +1,3 @@
+Makefile
+Cask
+.gitignore
\ No newline at end of file
diff --git a/elpa/persist-0.6.1/persist-autoloads.el b/elpa/persist-0.6.1/persist-autoloads.el
new file mode 100644 (file)
index 0000000..e621172
--- /dev/null
@@ -0,0 +1,28 @@
+;;; persist-autoloads.el --- automatically extracted autoloads (do not edit)   -*- lexical-binding: t -*-
+;; Generated by the `loaddefs-generate' function.
+
+;; This file is part of GNU Emacs.
+
+;;; Code:
+
+(add-to-list 'load-path (or (and load-file-name (directory-file-name (file-name-directory load-file-name))) (car load-path)))
+
+
+\f
+;;; Generated autoloads from persist.el
+
+(register-definition-prefixes "persist" '("persist-"))
+\f
+;;; End of scraped data
+
+(provide 'persist-autoloads)
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; no-native-compile: t
+;; coding: utf-8-emacs-unix
+;; End:
+
+;;; persist-autoloads.el ends here
diff --git a/elpa/persist-0.6.1/persist-pkg.el b/elpa/persist-0.6.1/persist-pkg.el
new file mode 100644 (file)
index 0000000..8b6e40f
--- /dev/null
@@ -0,0 +1,2 @@
+;; Generated package description from persist.el  -*- no-byte-compile: t -*-
+(define-package "persist" "0.6.1" "Persist Variables between Emacs Sessions" '((emacs "26.1")) :commit "5ea8f32ef50ce2b444d6918e17eedce9f74629af" :url "https://elpa.gnu.org/packages/persist.html" :authors '(("Phillip Lord" . "phillip.lordNOSPAMrusset.org.uk")) :maintainer '("Joseph Turner" . "persist-elNOSPAMbreatheoutbreathe.in"))
diff --git a/elpa/persist-0.6.1/persist.el b/elpa/persist-0.6.1/persist.el
new file mode 100644 (file)
index 0000000..49b3e9b
--- /dev/null
@@ -0,0 +1,249 @@
+;;; persist.el --- Persist Variables between Emacs Sessions -*- lexical-binding: t -*-
+
+;; Copyright (C) 2019, 2024 Free Software Foundation, Inc.
+
+;; Author: Phillip Lord <phillip.lordNOSPAMrusset.org.uk>
+;; Maintainer: Joseph Turner <persist-elNOSPAMbreatheoutbreathe.in>
+;; Package-Type: multi
+;; Package-Requires: ((emacs "26.1"))
+;; Version: 0.6.1
+
+;; The contents of this file are subject to the GPL License, Version 3.0.
+
+;; This file is not part of Emacs
+
+;; This program is free software: you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; This package provides variables which persist across sessions.
+
+;; The main entry point is `persist-defvar' which behaves like
+;; `defvar' but which persists the variables between session.  Variables
+;; are automatically saved when Emacs exits.
+
+;; Other useful functions are `persist-save' which saves the variable
+;; immediately, `persist-load' which loads the saved value,
+;; `persist-reset' which resets to the default value.
+
+;; Values are stored in a directory in `user-emacs-directory', using
+;; one file per value.  This makes it easy to delete or remove unused
+;; variables.
+
+;;; Code:
+
+(defvar persist--directory-location
+  (locate-user-emacs-file "persist")
+  "The location of persist directory.")
+
+(defvar persist--symbols nil
+  "List of symbols to persist.")
+
+(defvar persist-load-hook nil
+  "Special hook run on loading a variable.
+
+Hook functions are called with two values: the symbol and the
+value it will be set to.  If any function returns nil, the
+variable is not set to the value.")
+
+(defun persist--file-location (symbol)
+  "Return the file name at which SYMBOL does or will persist."
+  (expand-file-name
+   (symbol-name symbol)
+   (or (get symbol 'persist-location)
+       persist--directory-location)))
+
+(defun persist--defvar-1 (symbol location)
+  "Set symbol up for persistence."
+  (when location
+    (persist-location symbol location))
+  (persist-symbol symbol (symbol-value symbol))
+  (persist-load symbol))
+
+(defmacro persist-defvar (symbol initvalue docstring &optional location)
+  "Define SYMBOL as a persistent variable and return SYMBOL.
+
+This form is nearly equivalent to `defvar', except that the
+variable persists between Emacs sessions.
+
+It does not support the optional parameters.  Both INITVALUE and
+DOCSTRING need to be given."
+  ;; We cannot distinguish between calls with initvalue of nil and a
+  ;; single parameter call. Unfortunately, these two calls have
+  ;; different semantics -- the single arity shuts up the byte
+  ;; compiler, but does not define the symbol. So, don't support a
+  ;; single arity persist-defvar.
+
+  ;; Don't support 2-arity calls either because we are lazy and
+  ;; because if you want to persist it, you want to doc it.
+  (declare (debug (symbolp form stringp &optional form))
+           (doc-string 3)
+           (indent defun))
+  ;; Define inside progn so the byte compiler sees defvar
+  `(progn
+     (defvar ,symbol ,initvalue ,docstring)
+     ;; Access initvalue through its symbol because the defvar form
+     ;; has to stay at first level within a progn
+     (persist--defvar-1 ',symbol ,location)
+     ',symbol))
+
+(defun persist-location (symbol directory)
+  "Set the directory for persisting the value of symbol.
+
+This does not force the loading of value from this directory, so
+to persist a variable, you will normally need to call
+`persist-load' to load a previously saved location."
+  (put symbol 'persist-location (expand-file-name directory)))
+
+(defun persist-symbol (symbol &optional initvalue)
+  "Make SYMBOL a persistent variable.
+
+If non-nil, INITVALUE is the value to which SYMBOL will be set if
+`persist-reset' is called.  Otherwise, the INITVALUE will be the
+current `symbol-value' of SYMBOL.
+
+INITVALUE is set for the session and will itself not persist
+across sessions.
+
+This does force the loading of value from this directory, so to
+persist a variable, you will normally need to call `persist-load'
+to load a previously saved location."
+  (let ((initvalue (or initvalue (symbol-value symbol))))
+    (add-to-list 'persist--symbols symbol)
+    (put symbol 'persist t)
+    (put symbol 'persist-default (persist-copy initvalue))))
+
+(defun persist--persistant-p (symbol)
+  "Return non-nil if SYMBOL is a persistent variable."
+  (get symbol 'persist))
+
+(defun persist-save (symbol)
+  "Save SYMBOL now.
+
+Normally, it should not be necessary to call this explicitly, as
+variables persist automatically when Emacs exits."
+  (unless (persist--persistant-p symbol)
+    (error (format
+            "Symbol %s is not persistent" symbol)))
+  (let ((symbol-file-loc (persist--file-location symbol)))
+    (if (persist-equal (symbol-value symbol)
+                       (persist-default symbol))
+        (when (file-exists-p symbol-file-loc)
+          (delete-file symbol-file-loc))
+      (let ((dir-loc
+             (file-name-directory symbol-file-loc)))
+        (unless (file-exists-p dir-loc)
+          (mkdir dir-loc))
+        (with-temp-buffer
+          (let (print-level
+                print-length
+                print-quoted
+                (print-escape-control-characters t)
+                (print-escape-nonascii t)
+                (print-circle t))
+            (print (symbol-value symbol) (current-buffer)))
+          (write-region (point-min) (point-max)
+                        symbol-file-loc
+                        nil 'quiet))))))
+
+(defun persist-default (symbol)
+  "Return the default value for SYMBOL."
+  (get symbol 'persist-default))
+
+(defun persist-reset (symbol)
+  "Set the value of SYMBOL to a copy of the default."
+  (set symbol (persist-copy (persist-default symbol))))
+
+(defun persist-load (symbol)
+  "Load the saved value of SYMBOL."
+  (when (file-exists-p (persist--file-location symbol))
+    (with-temp-buffer
+      (insert-file-contents (persist--file-location symbol))
+      (let ((val (read (current-buffer))))
+        (when (run-hook-with-args-until-failure 'persist-load-hook
+                                                symbol val)
+          (set symbol val))))))
+
+(defun persist-unpersist (symbol)
+  "Stop the value in SYMBOL from persisting.
+
+This does not remove any saved value of SYMBOL."
+  (put symbol 'persist nil)
+  (setq persist--symbols
+        (remove symbol persist--symbols)))
+
+(defun persist--save-all ()
+  "Save all persistent symbols."
+  (mapc 'persist-save persist--symbols))
+
+;; Save on kill-emacs-hook anyway
+(add-hook 'kill-emacs-hook
+          'persist--save-all)
+
+(defun persist-equal (a b)
+  "Return non-nil when the values of A and B are equal.
+A and B are compared using `equal' unless they are both hash
+tables.  In that case, the following are compared:
+
+- hash table count
+- hash table predicate
+- values, using `persist-equal'"
+  (if (and (hash-table-p a) (hash-table-p b))
+      (and (= (hash-table-count a) (hash-table-count b))
+           (eq (hash-table-test a) (hash-table-test b))
+           (catch 'done
+             (maphash
+              (lambda (key a-value)
+                (unless (persist-equal a-value (gethash key b (not a-value)))
+                  (throw 'done nil)))
+              a)
+             t))
+    (equal a b)))
+
+(defun persist-copy-tree (tree &optional vectors-and-records)
+  "Make a copy of TREE.
+If TREE is a cons cell, this recursively copies both its car and its cdr.
+Contrast to `copy-sequence', which copies only along the cdrs.
+With the second argument VECTORS-AND-RECORDS non-nil, this
+traverses and copies vectors and records as well as conses."
+  (declare (side-effect-free error-free))
+  (if (consp tree)
+      (let (result)
+       (while (consp tree)
+         (let ((newcar (car tree)))
+           (if (or (consp (car tree))
+                    (and vectors-and-records
+                         (or (vectorp (car tree)) (recordp (car tree)))))
+               (setq newcar (persist-copy-tree (car tree) vectors-and-records)))
+           (push newcar result))
+         (setq tree (cdr tree)))
+       (nconc (nreverse result)
+               (if (and vectors-and-records (or (vectorp tree) (recordp tree)))
+                   (persist-copy-tree tree vectors-and-records)
+                 tree)))
+    (if (and vectors-and-records (or (vectorp tree) (recordp tree)))
+       (let ((i (length (setq tree (copy-sequence tree)))))
+         (while (>= (setq i (1- i)) 0)
+           (aset tree i (persist-copy-tree (aref tree i) vectors-and-records)))
+         tree)
+      tree)))
+
+(defun persist-copy (obj)
+  "Return copy of OBJ."
+  (if (hash-table-p obj)
+      (copy-hash-table obj)
+    (persist-copy-tree obj t)))
+
+(provide 'persist)
+;;; persist.el ends here
diff --git a/elpa/persist-0.6.1/persist.texi b/elpa/persist-0.6.1/persist.texi
new file mode 100644 (file)
index 0000000..99f61a2
--- /dev/null
@@ -0,0 +1,153 @@
+\input texinfo
+@setfilename persist.info
+@settitle persist persistent variables
+
+@dircategory Emacs
+@direntry
+* Persist: (persist).  Persistent variables for Emacs.
+@end direntry
+
+@copying
+Copyright @copyright{} 2019 Phillip Lord
+
+@quotation
+Permission is granted to copy, distribute and/or modify this document
+under the terms of the GNU Free Documentation License, Version 1.2 or
+any later version published by the Free Software Foundation; with no
+Invariant Sections, with the Front-Cover, or Back-Cover Texts.  A copy of
+the license is included in the section entitled ``GNU Free Documentation
+License'' in the Emacs manual.
+
+This document is part of a collection distributed under the GNU Free
+Documentation License.  If you want to distribute this document
+separately from the collection, you can do so by adding a copy of the
+license to the document, as described in section 6 of the license.
+
+All Emacs Lisp code contained in this document may be used, distributed,
+and modified without restriction.
+@end quotation
+@end copying
+
+@titlepage
+@title Persist -- Persistent Variables for Emacs
+@author by Phillip Lord
+@page
+@insertcopying
+@end titlepage
+
+@contents
+
+@node Top
+@top Persist -- Persistent Variables for Emacs
+
+Persist is a library for making variables persistent; that it, their
+state can be changed from the default and the new value will remain even
+after Emacs has been closed and restarted.
+
+@menu
+* Persist::                     Simple Usage
+* The details::        All functions for interacting with Persist
+* Comparison::                  How this relates to other, similar techniques
+* Implementation::              How variables are saved
+@end menu
+
+@node Persist
+@section Persist
+
+This section describes simple usage of persist.
+
+@defmac persist-defvar (var initvalue docstring) body@dots{}
+This macro is equivalent in form to @code{defvar}, except any changes to
+the value of @code{var} will persist between sessions.  This macro does
+not support the lower arity versions of @code{defvar}. Both an
+@code{initvalue} and @code{docstring} needs to be provided.
+@end defmac
+
+@example
+@group
+(persist-defvar my-persistant-variable 10
+   "A variable of no purpose.
+   
+This variable is persistent between sessions")
+@end group
+@end example
+
+
+@node The details
+@section The details
+
+
+@defmac persist-defvar (var initvalue docstring) body@dots{}
+This macro is equivalent to @code{defvar} and can be used to make a
+variable persistent.
+@end defmac
+
+@defun persist-symbol (symbol &optional initvalue)
+This function takes @code{symbol} for an existing, non-persistent variable
+and makes it persistent. If @code{initvalue} is not given, then the
+current value is used. For package developers, @code{persist-defvar}
+would generally be preferred; this function might be useful for making
+third-party variables persistent.
+@end defun
+
+@example
+@group
+(defvar my-persistant-variable 10
+    "A variable of no purpose")
+
+(persist-symbol 'my-persistant-variable 10)
+@end group
+@end example
+
+@defun persist-save (symbol)
+This function saves @code{symbol} immediately rather than waiting till
+the normal time
+@end defun
+
+@defun persist-default (symbol)
+Return the default value for @code{symbol}. The default value is
+actually set for each session and does not persist from session to
+session, although if the value is set by either @code{persist-defvar} or
+@code{persist-symbol} saved it in a file, it will be set to the same
+value across sessions.
+@end defun
+
+@defun persist-reset (symbol)
+Change the value of @code{symbol} to the last saved value if it exists.
+@end defun
+
+@defun persist-location (symbol directory)
+Values are usually persisted to a standard location; it is possible to
+change this for individual symbol using this function. Be aware that
+this does not call @code{persist-load}, so this will not restore a
+previously saved value.
+@end defun
+
+@node Comparison
+@section Comparison
+
+There are several other packages which also persist aspects of Emacs
+across sessions, however, these fulfil a different purpose.
+
+Custom persists values of variables across sessions. However, it does
+this for user options, and is associated with a user interface for
+editing the value.
+
+desktop.el is also user-centric and is aimed at persisting the session
+in terms of buffers, modes and minor modes. It can be used to persist
+individual variables, but this will also save the session which the user
+may or may not want.
+
+savehist.el can save individual variables but, as with desktop.el, is a
+a global setting and has other implications such as saving mini-buffer
+history.
+
+@node Implementation
+@section Implementation
+
+persist is implemented by saving values for each symbol into an
+different. This makes it relatively easy to update or delete the stored
+value for a variable by hand if necessary. It should scale to 10 or 100
+variables, but may get a bit slow after this.
+
+@bye
diff --git a/elpa/persist-0.6.1/test/persist-tests.el b/elpa/persist-0.6.1/test/persist-tests.el
new file mode 100644 (file)
index 0000000..d571325
--- /dev/null
@@ -0,0 +1,146 @@
+(require 'persist)
+(require 'seq)
+
+
+(defmacro with-local-temp-persist (&rest body)
+  (declare (debug body))
+  `(unwind-protect
+       (let ((persist--directory-location "./persist/")
+             (persist--symbols nil))
+         ,@body)
+     (delete-directory "./persist" t)))
+
+(ert-deftest test-persist-symbol ()
+  (should
+   (let ((persist--symbols nil)
+         (sym (cl-gensym)))
+     (persist-symbol sym 10)
+     (seq-contains persist--symbols sym))))
+
+(ert-deftest test-persist-save-only-persistant ()
+  ;; do not save not persist variables
+  (should-error
+   (with-local-temp-persist
+    (persist-save (cl-gensym)))
+   :type 'error
+   :exclude-subtypes t))
+
+(defmacro persist-test-persist-save (init default change printed-changed)
+  "Test persisting symbols.
+- symbol is not persisted when value is set to INIT and default
+  value is set to DEFAULT.
+- symbol is persisted when value is changed according to CHANGE.
+- persisted file contents match PRINTED-CHANGED.
+- symbol is not persisted after value is set back to DEFAULT."
+  `(with-local-temp-persist
+    (let ((sym (cl-gensym)))
+      (should-not (file-exists-p (persist--file-location sym)))
+      (set sym ,init)
+      (persist-symbol sym ,default)
+      (persist-save sym)
+      (should t)
+      (should-not (file-exists-p (persist--file-location sym)))
+      ,change
+      (persist-save sym)
+      (should (file-exists-p (persist--file-location sym)))
+      (should
+       (string-match-p
+        ,printed-changed
+        (with-temp-buffer
+          (insert-file-contents (persist--file-location sym))
+          (buffer-string))))
+      (set sym ,default)
+      (persist-save sym)
+      (should-not (file-exists-p (persist--file-location sym))))))
+
+(ert-deftest test-persist-save-number ()
+  "Test saving number."
+  (persist-test-persist-save 1 1 (set sym 2) "2"))
+
+(ert-deftest test-persist-save-string ()
+  "Test saving string."
+  (persist-test-persist-save "foo" "foo" (set sym "bar") "bar"))
+
+(ert-deftest test-persist-save-hash ()
+  "Test saving hash table."
+  (let* ((hash (make-hash-table))
+         (default (copy-hash-table hash)))
+    (persist-test-persist-save hash default
+                               (puthash 'foo "bar" (symbol-value sym))
+                               "#s(hash-table size 65 test eql rehash-size 1.5 rehash-threshold 0.8125 data (foo \"bar\"))")))
+
+(ert-deftest test-persist-save-record ()
+  "Test saving record."
+  (let* ((rec (record 'foo 'a 'b))
+         (default (copy-sequence rec)))
+    (persist-test-persist-save rec default
+                               (setf (aref (symbol-value sym) 2) 'quux)
+                               "#s(foo a quux)")))
+
+(ert-deftest test-persist-load ()
+  (with-local-temp-persist
+   (let ((sym (cl-gensym)))
+     (set sym 10)
+     ;; set this different to force save
+     (persist-symbol sym 1)
+     (persist-save sym)
+     (should (equal 10 (symbol-value sym)))
+     (set sym 30)
+     (should (equal 30 (symbol-value sym)))
+     (persist-load sym)
+     (should (equal 10 (symbol-value sym))))))
+
+(ert-deftest test-persist-remove ()
+  (with-local-temp-persist
+   (let ((sym (cl-gensym)))
+     (should-not (persist--persistant-p sym))
+     (persist-symbol sym 10)
+     (should (persist--persistant-p sym))
+     (persist-unpersist sym)
+     (should-not (persist--persistant-p sym)))))
+
+(ert-deftest test-persist-defvar ()
+  (with-local-temp-persist
+   (defvar test-no-persist-variable 10 "docstring")
+   (persist-defvar test-persist-variable 20 "docstring")
+   (should-not (persist--persistant-p 'test-no-persist-variable))
+   (should (persist--persistant-p 'test-persist-variable))
+   (should (= 20
+              (persist-default 'test-persist-variable)))))
+
+(ert-deftest test-persist-location ()
+  (unwind-protect
+      (let ((sym (cl-gensym)))
+        (delete-directory "./persist-defined-location" t)
+        (set sym 10)
+        (persist-symbol sym 10)
+        (persist-location sym "./persist-defined-location")
+        (should
+         (equal (expand-file-name
+                 (symbol-name sym)
+                 "./persist-defined-location/")
+                (persist--file-location sym)))
+        (persist-save sym)
+        (should-not (file-exists-p (persist--file-location sym)))
+        (set sym 20)
+        (persist-save sym)
+        (should (file-exists-p (persist--file-location sym)))
+        (should
+         (string-match-p
+          "20"
+          (with-temp-buffer
+            (insert-file-contents (persist--file-location sym))
+            (buffer-string))))
+        (should-error
+         (persist-save 'fred)))
+    (delete-directory "./persist-defined-location" t)))
+
+(ert-deftest test-persist-reset ()
+  "Symbol should be reset to a copy of the default."
+  (with-local-temp-persist
+   (persist-defvar persist--test-reset-variable (make-hash-table) "docstring")
+   (should-not (eq persist--test-reset-variable
+                   (persist-default 'persist--test-reset-variable)))
+   (persist-reset 'persist--test-reset-variable)
+   (should-not (eq persist--test-reset-variable
+                   (persist-default 'persist--test-reset-variable)))))