--- /dev/null
+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
--- /dev/null
+Makefile
+Cask
+.gitignore
\ No newline at end of file
--- /dev/null
+;;; 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
--- /dev/null
+;; 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"))
--- /dev/null
+;;; 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
--- /dev/null
+\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
--- /dev/null
+(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)))))