Change: Refactor, improve docstrings, argument handling, etc.

Move some code between functions and macros to make more sense and be
more flexible.
This commit is contained in:
Adam Porter 2018-07-10 08:27:54 -05:00
parent c605ccbaf3
commit 8bfb65d715
2 changed files with 84 additions and 40 deletions

View file

@ -41,26 +41,66 @@
;; FIXME: DRY these two macros.
(cl-defmacro org-agenda-ng (files pred-body)
"Display an agenda-like buffer of entries in FILES that match PRED-BODY."
(declare (indent defun))
`(org-agenda-ng--agenda ,files
(byte-compile (lambda ()
(cl-symbol-macrolet ((= #'=)
(< #'<)
(> #'>)
(<= #'<=)
(>= #'>=))
,pred-body)))
#'org-agenda-ng--format-element))
(cl-defmacro org-agenda-ng (&rest args)
"Display an agenda-like buffer of entries in FILES that match PRED.
FILES-OR-PRED is a sexp that is evaluated to get the list of
files to scan.
PRED is a predicate sexp which is evaluated on each entry to test
whether it matches. This should be a form used by `org-ql'.
The predicate may be passed as FILES-OR-PRED and PRED may be left
nil, in which case the list of files will automatically be set to
the value of calling `org-agenda-files'.
SORT is a list of sorting keys: `deadline', `scheduled',
`date' (matching either `deadline' or `scheduled'), `priority',
or `todo'.
NARROW, when non-nil, means to respect narrowing in buffers.
When nil, buffers are widened before being searched."
(declare (indent defun)
(advertised-calling-convention '(files-or-pred &optional pred &key sort narrow) nil))
(cl-macrolet ((set-keyword-args (args)
`(setq sort (plist-get ,args :sort)
narrow (plist-get ,args :narrow))))
(let ((files '(org-agenda-files))
pred sort narrow)
;; Parse args manually (so we can leave FILES nil for a default argument).
(pcase args
(`(,arg-files ,arg-pred . ,(and rest (guard (keywordp (car rest)))))
(setq files arg-files
pred arg-pred)
(set-keyword-args rest))
(`(,arg-pred . ,(and rest (guard (keywordp (car rest)))))
(setq pred arg-pred)
(set-keyword-args rest)))
;; Call --agenda
`(org-agenda-ng--agenda ,files
(byte-compile (lambda ()
(cl-symbol-macrolet ((= #'=) (< #'<) (> #'>) (<= #'<=) (>= #'>=))
,pred)))
:sort ',sort))))
;;;; Functions
;; TODO: Move the action-fn down into --filter-buffer, so users can avoid calling the
;; headline-parser when they don't need it.
(cl-defun org-agenda-ng--agenda (files pred action-fn)
(let* ((entries (org-ql--query files pred action-fn))
(cl-defun org-agenda-ng--agenda (files pred &key action-fn sort)
;; `org-ql--query' uses `org-element-headline-parser' by default, which we then map
;; `org-agenda-ng--format-element' across to get formatted, propertized strings for the agenda.
;; NOTE: `org-element-headline-parser' should remain the low-level action function, because the
;; sorting functions work on Org elements (so e.g. if we put `org-agenda-ng--format-element' as
;; the low-level action function, sorting would do nothing, because the sorting functions would
;; not find any data to sort on). IOW we have to call `org-agenda-ng--format-element' here, not
;; pass it to lower functions.
(declare (indent defun))
(let* ((entries (mapcar #'org-agenda-ng--format-element
(org-ql--query files
pred
:sort sort)))
(result-string (org-agenda-finalize-entries entries 'agenda))
(target-buffer (get-buffer-create "test-agenda-ng")))
(with-current-buffer target-buffer