1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
;;; elephant.el --- Remember variables and modes -*- lexical-binding: t; -*-
;;; Code:
(defmacro elephant-remember (alist)
"Setup a closure remembering symbols to apply with
`remember-reset'. The variables will be renamed using TEMPLATE.
ALIST contains cells of the form (SYMBOL . NEW-VALUE), where
SYMBOL is a variable or mode name, and its value is what to set
after `remember-set'."
(unless lexical-binding
(user-error "`elephant' requires lexical binding."))
(let* ((template (format "elephant--%s-%%s" (gensym)))
(reset-fn (intern (format template "reset"))))
(cl-destructuring-bind (let-list fn-set-list fn-reset-list)
(cl-loop
for (sym . val) in (if (symbolp alist) (symbol-value alist) alist)
as rem = (intern (format template sym))
collect (list rem sym)
into let-list
collect (cond ((eq val 'enable)
`(,sym +1))
((eq val 'disable)
`(,sym -1))
(t `(setq-local ,sym ,val)))
into fn-set-list
collect (cond ((memq val '(enable disable))
`(progn (,sym (if ,rem +1 -1))
(fmakunbound ',rem)))
(t `(progn (setq-local ,sym ,rem)
(makunbound ',rem))))
into fn-reset-list
finally return (list let-list
fn-set-list
fn-reset-list))
`(progn
(defvar-local ,reset-fn nil
"Function to recall values from `elephant-remember'.")
(let ,let-list
(setf (symbol-function ',reset-fn)
(lambda ()
,@fn-reset-list
(redraw-display)
(fmakunbound ',reset-fn))))
,@fn-set-list
',reset-fn))))
(defun elephant-forget ()
"Forget all symbols generated by `elephant-remember'."
)
(provide 'elephant)
;;; elephant.el ends here
|