add lisp packages

This commit is contained in:
2020-12-05 21:29:49 +01:00
parent 85e20365ae
commit a6e2395755
7272 changed files with 1363243 additions and 0 deletions

3
lisp/persist/.elpaignore Normal file
View File

@@ -0,0 +1,3 @@
Makefile
Cask
.gitignore

4
lisp/persist/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
/.cask
/makefile-local
/persist.html
/dist/

6
lisp/persist/Cask Normal file
View File

@@ -0,0 +1,6 @@
(source melpa-stable)
(package-file "persist.el")
(development
(depends-on "assess"))

29
lisp/persist/Makefile Normal file
View File

@@ -0,0 +1,29 @@
EMACS ?= emacs
CASK ?= cask
-include makefile-local
ifdef EMACS
EMACS_ENV=EMACS=$(EMACS)
endif
test: install just-test
just-test:
$(EMACS_ENV) $(CASK) emacs --batch -q \
--directory=. \
--load assess-discover.el \
--eval '(assess-discover-run-and-exit-batch t)'
install:
$(EMACS_ENV) $(CASK) install
html:
texi2html persist.texi
push-elpa:
git push elpa HEAD:externals/persist
pull-elpa:
git pull elpa externals/persist

View File

@@ -0,0 +1,2 @@
;; Generated package description from persist.el -*- no-byte-compile: t -*-
(define-package "persist" "0.4" "Persist Variables between Emacs Sessions" 'nil :url "http://elpa.gnu.org/packages/persist.html" :authors '(("Phillip Lord" . "phillip.lord@russet.org.uk")) :maintainer '("Phillip Lord" . "phillip.lord@russet.org.uk"))

183
lisp/persist/persist.el Normal file
View File

@@ -0,0 +1,183 @@
;;; persist.el --- Persist Variables between Emacs Sessions -*- lexical-binding: t -*-
;; Copyright (C) 2019 Free Software Foundation, Inc.
;; Author: Phillip Lord <phillip.lord@russet.org.uk>
;; Maintainer: Phillip Lord <phillip.lord@russet.org.uk>
;; Package-Type: multi
;; Version: 0.4
;; 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 <http://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 persistance."
(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 persistant 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))
;; 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 persistant 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 initvalue)))
(defun persist--persistant-p (symbol)
"Return non-nil if SYMBOL is a persistant 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 persistant" symbol)))
(unless (equal (symbol-value symbol)
(persist-default symbol))
(let ((dir-loc
(file-name-directory
(persist--file-location symbol))))
(unless (file-exists-p dir-loc)
(mkdir dir-loc)))
(with-temp-buffer
(print (symbol-value symbol) (current-buffer))
(write-region (point-min) (point-max)
(persist--file-location symbol)
nil 'quiet))))
(defun persist-default (symbol)
"Return the default value for SYMBOL."
(get symbol 'persist-default))
(defun persist-reset (symbol)
"Reset the value of SYMBOL to the default."
(set symbol (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 persistant symbols."
(mapc 'persist-save persist--symbols))
;; Save on kill-emacs-hook anyway
(add-hook 'kill-emacs-hook
'persist--save-all)
(provide 'persist)
;;; persist.el ends here

153
lisp/persist/persist.texi Normal file
View File

@@ -0,0 +1,153 @@
\input texinfo
@setfilename persist.info
@settitle persist persistant variables
@dircategory Emacs
@direntry
* Persist: (persist). Persistant 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 -- Persistant Variables for Emacs
@author by Phillip Lord
@page
@insertcopying
@end titlepage
@contents
@node Top
@top Persist -- Persistant Variables for Emacs
Perist is a library for making variables persistant; 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 persistant 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 persistant.
@end defmac
@defun persist-symbol (symbol &optional initvalue)
This function takes @code{symbol} for an existing, non-persistant variable
and makes it persistant. If @code{initvalue} is not given, then the
current value is used. For package developers, @code{persist-defvar}
would generally be prefered; this function might be useful for making
third-party variables persistant.
@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

View File

@@ -0,0 +1,6 @@
## what ever we called, don't do it here
default:
$(MAKE) -C ..
$(MAKECMDGOALS):
$(MAKE) -C .. $(MAKECMDGOALS)

View File

@@ -0,0 +1,127 @@
(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))
(ert-deftest test-persist-save ()
(with-local-temp-persist
(let ((sym (cl-gensym)))
;; precondition
(should-not (file-exists-p (persist--file-location sym)))
(set sym 10)
(persist-symbol sym 10)
(persist-save sym)
(should t)
(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)))))
(ert-deftest test-persist-save-non-number ()
"Test saving something that is not a number.
`test-persist-save' missed "
(with-local-temp-persist
(let ((sym (cl-gensym)))
(set sym "fred")
(persist-symbol sym "fred")
(persist-save sym)
(should t)
(should-not (file-exists-p (persist--file-location sym)))
(set sym "george")
(persist-save sym)
(should (file-exists-p (persist--file-location sym)))
(should
(string-match-p
"george"
(with-temp-buffer
(insert-file-contents (persist--file-location sym))
(buffer-string)))))))
(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)))