diff options
Diffstat (limited to 'lisp/+org-capture.el')
-rw-r--r-- | lisp/+org-capture.el | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/lisp/+org-capture.el b/lisp/+org-capture.el new file mode 100644 index 0000000..1631bdd --- /dev/null +++ b/lisp/+org-capture.el | |||
@@ -0,0 +1,82 @@ | |||
1 | ;;; +org-capture.el -*- lexical-binding: t; -*- | ||
2 | |||
3 | ;;; Code: | ||
4 | |||
5 | (require 'cl-lib) | ||
6 | ;; We don't require `org-capture' here because I'll have to require this library | ||
7 | ;; to init.el /before/ org-capture is fully needed. | ||
8 | |||
9 | (defun +org-capture--get (key &optional list) | ||
10 | "Find KEY in LIST, or return nil. | ||
11 | LIST defaults to `org-capture-templates'." | ||
12 | (alist-get key (or list org-capture-templates) nil nil #'equal)) | ||
13 | |||
14 | ;; Set it up as a generic value. Based on the one for `alist-get'. | ||
15 | (gv-define-expander +org-capture--get | ||
16 | (lambda (do key &optional alist) | ||
17 | (setq alist (or alist org-capture-templates)) | ||
18 | (macroexp-let2 macroexp-copyable-p k key | ||
19 | (gv-letplace (getter setter) alist | ||
20 | (macroexp-let2 nil p `(assoc ,k ,getter 'equal) | ||
21 | (funcall do `(cdr ,p) | ||
22 | (lambda (v) | ||
23 | (macroexp-let2 nil v v | ||
24 | (let ((set-exp | ||
25 | `(if ,p (setcdr ,p ,v) | ||
26 | ,(funcall setter | ||
27 | `(cons (setq ,p (cons ,k ,v)) | ||
28 | ,getter))))) | ||
29 | `(progn | ||
30 | ,set-exp | ||
31 | ,v)))))))))) | ||
32 | |||
33 | (defun +org-capture-sort (&optional list) | ||
34 | "Sort LIST by string keys. | ||
35 | LIST is a symbol and defaults to `org-capture-templates'." | ||
36 | (setq list (or list 'org-capture-templates)) | ||
37 | (set list (sort (symbol-value list) (lambda (a b) | ||
38 | (string< (car a) (car b)))))) | ||
39 | |||
40 | ;;;###autoload | ||
41 | (defun +org-capture-templates-setf (key value &optional list sort-after) | ||
42 | "Add KEY to LIST, using `setf'. | ||
43 | LIST is a symbol and defaults to `org-capture-templates' -- so | ||
44 | this function sets values on a list that's structured as such. | ||
45 | |||
46 | Thus, KEY is a string key. If it's longer than one character, | ||
47 | this function will search LIST for each successive run of | ||
48 | characters before the final, ensuring sub-lists exist of the | ||
49 | form (CHARS DESCRIPTION). | ||
50 | |||
51 | For example, if KEY is \"abc\", first a LIST item of the form (a | ||
52 | DESCRIPTION), if non-existant, will be added to the list (with a | ||
53 | default description), then an item of the | ||
54 | form (\"ab\" DESCRIPTION), before adding (KEY VALUE) to the LIST. | ||
55 | |||
56 | VALUE is the template or group header required for | ||
57 | `org-capture-templates', which see. | ||
58 | |||
59 | SORT-AFTER, when set to t, will call | ||
60 | `+org-capture-templates-sort' after setting, to ensure org can | ||
61 | properly process the variable." | ||
62 | ;; LIST defaults to `org-capture-templates' | ||
63 | (declare (indent 2)) | ||
64 | (unless list (setq list 'org-capture-templates)) | ||
65 | ;; Ensure VALUE is a list to cons properly | ||
66 | (unless (listp value) (setq value (list value))) | ||
67 | (when (> (length key) 1) | ||
68 | ;; Check for existence of groups. | ||
69 | (let ((expected (cl-loop for i from 1 to (1- (length key)) | ||
70 | collect (substring key 0 i) into keys | ||
71 | finally return keys))) | ||
72 | (cl-loop for ek in expected | ||
73 | if (not (+org-capture--get ek (symbol-value list))) do | ||
74 | (setf (+org-capture--get ek (symbol-value list)) | ||
75 | (list (format "(Group %s)" ek)))))) | ||
76 | (prog1 ;; Set KEY to VALUE | ||
77 | (setf (+org-capture--get key (symbol-value list)) value) | ||
78 | ;; Sort after, maybe | ||
79 | (when sort-after (+org-capture-sort list)))) | ||
80 | |||
81 | (provide '+org-capture) | ||
82 | ;;; +org-capture.el ends here | ||