emacs/lisp/+org-capture.el

106 lines
4.2 KiB
EmacsLisp
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;; +org-capture.el -*- lexical-binding: t; -*-
;;; Code:
(require 'cl-lib)
(require 'acdw)
;; We don't require `org-capture' here because I'll have to require this library
;; to init.el /before/ org-capture is fully needed. But I do need to declare
;; `org-capture-templates'.
(defvar org-capture-templates nil)
(defun +org-capture--get (key &optional list)
"Find KEY in LIST, or return nil.
LIST defaults to `org-capture-templates'."
(alist-get key (or list org-capture-templates) nil nil #'equal))
;; Set it up as a generic value. Based on the one for `alist-get'.
(gv-define-expander +org-capture--get
(lambda (do key &optional alist)
(setq alist (or alist org-capture-templates))
(macroexp-let2 macroexp-copyable-p k key
(gv-letplace (getter setter) alist
(macroexp-let2 nil p `(assoc ,k ,getter 'equal)
(funcall do `(cdr ,p)
(lambda (v)
(macroexp-let2 nil v v
(let ((set-exp
`(if ,p (setcdr ,p ,v)
,(funcall setter
`(cons (setq ,p (cons ,k ,v))
,getter)))))
`(progn
,set-exp
,v))))))))))
(defun +org-capture-sort (&optional list)
"Sort LIST by string keys.
LIST is a symbol and defaults to `org-capture-templates'."
(setq list (or list 'org-capture-templates))
(set list (sort (symbol-value list) (lambda (a b)
(string< (car a) (car b))))))
(defun +org-capture-sort-after-init (&optional list)
"Sort LIST with `+org-capture-sort' after Emacs init."
(+ensure-after-init #'+org-capture-sort))
;;;###autoload
(defun +org-capture-templates-setf (key value &optional list sort-after)
"Add KEY to LIST, using `setf'.
LIST is a symbol and defaults to `org-capture-templates' -- so
this function sets values on a list that's structured as such.
Thus, KEY is a string key. If it's longer than one character,
this function will search LIST for each successive run of
characters before the final, ensuring sub-lists exist of the
form (CHARS DESCRIPTION).
For example, if KEY is \"abc\", first a LIST item of the form (a
DESCRIPTION), if non-existant, will be added to the list (with a
default description), then an item of the
form (\"ab\" DESCRIPTION), before adding (KEY VALUE) to the LIST.
VALUE is the template or group header required for
`org-capture-templates', which see.
SORT-AFTER, when set to t, will call
`+org-capture-templates-sort' after setting, to ensure org can
properly process the variable."
;; LIST defaults to `org-capture-templates'
(declare (indent 2))
(unless list (setq list 'org-capture-templates))
;; Ensure VALUE is a list to cons properly
(unless (listp value) (setq value (list value)))
(when (> (length key) 1)
;; Check for existence of groups.
(let ((expected (cl-loop for i from 1 to (1- (length key))
collect (substring key 0 i) into keys
finally return keys)))
(cl-loop for ek in expected
if (not (+org-capture--get ek (symbol-value list))) do
(setf (+org-capture--get ek (symbol-value list))
(list (format "(Group %s)" ek))))))
(prog1 ;; Set KEY to VALUE
(setf (+org-capture--get key (symbol-value list)) value)
;; Sort after, maybe
(when sort-after (+org-capture-sort list))))
(defun +org-template--ensure-path (keys &optional list)
"Ensure path of keys exists in `org-capture-templates'."
(unless list (setq list 'org-capture-templates))
(when (> (length key) 1)
;; Check for existence of groups.
(let ((expected (cl-loop for i from 1 to (1- (length key))
collect (substring key 0 i) into keys
finally return keys)))
(cl-loop for ek in expected
if (not (+org-capture--get ek (symbol-value list))) do
(setf (+org-capture--get ek (symbol-value list))
(list (format "(Group %s)" ek)))))))
(defun +org-define-capture-template (keys title &rest args)
)
(provide '+org-capture)
;;; +org-capture.el ends here