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