From 2ddc69b64d38f8637e4be9bc1c59ab9bf04482b6 Mon Sep 17 00:00:00 2001 From: Adam Porter Date: Mon, 20 Aug 2018 08:17:25 -0500 Subject: [PATCH] Refactor agenda-ng buffer and use org-agenda-mode Using org-agenda-mode isn't exactly *correct*, but since we use some compatible text properties, it does give us some functionality for free, even if it isn't 100% compatible. Note that this should be considered experimental. It's not unimaginable that using some agenda buffer commands in the agenda-ng buffer could have unexpected consequences, including data corruption. However, basic ones like jumping to entries and org-agenda-priority seem to work. --- org-agenda-ng.el | 47 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/org-agenda-ng.el b/org-agenda-ng.el index 35e0e65..e972cc6 100644 --- a/org-agenda-ng.el +++ b/org-agenda-ng.el @@ -37,6 +37,11 @@ (require 'org-ql) +;;;; Variables + +(defvar org-agenda-ng-buffer-name "*Org Agenda NG*" + "Name of default `org-agenda-ng' buffer.") + ;;;; Macros ;; FIXME: DRY these two macros. @@ -45,7 +50,7 @@ "Display an agenda-like buffer of entries in FILES that match QUERY. FILES-OR-QUERY is a sexp that is evaluated to get the list of -files to scan. +buffers and files to scan. QUERY is an `org-ql' query. The query may be passed as FILES-OR-QUERY and QUERY may be left nil, in which case the list @@ -55,14 +60,18 @@ of files will automatically be set to the value of calling SORT is passed to `org-ql', which see.. NARROW, when non-nil, means to respect narrowing in buffers. -When nil, buffers are widened before being searched." +When nil, buffers are widened before being searched. + +BUFFER, when non-nil, is a buffer or buffer name to display the +agenda in, rather than the default." (declare (indent defun) - (advertised-calling-convention (files-or-query &optional query &key sort narrow) nil)) + (advertised-calling-convention (files-or-query &optional query &key sort narrow buffer) nil)) (cl-macrolet ((set-keyword-args (args) `(setq sort (plist-get ,args :sort) - narrow (plist-get ,args :narrow)))) + narrow (plist-get ,args :narrow) + buffer (plist-get ,args :buffer)))) (let ((files '(org-agenda-files)) - pred sort narrow) + query sort narrow buffer) ;; Parse args manually (so we can leave FILES nil for a default argument). ;; TODO: DRY this and org-ql, I think. (pcase args @@ -70,27 +79,28 @@ When nil, buffers are widened before being searched." ;; Files, query, and keyword args (FIXME: Can I combine this and the next one? Does it ;; matter if rest is nil or starts with a keyword?) (setq files arg-files - pred arg-pred) + query arg-pred) (set-keyword-args rest)) (`(,arg-pred . ,(and rest (guard (keywordp (car rest))))) ;; Query and keyword args, no files - (setq pred arg-pred) + (setq query arg-pred) (set-keyword-args rest)) (`(,arg-pred) ;; Only query - (setq pred arg-pred))) + (setq query arg-pred))) ;; Call --agenda `(org-agenda-ng--agenda ,files ;; TODO: Probably better to just use eval on org-ql rather than reimplementing parts of it here. - ',pred - :sort ',sort)))) + ',query + :sort ',sort + :buffer ,buffer)))) ;;;; 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 (buffers-files query &key sort) +(cl-defun org-agenda-ng--agenda (buffers-files query &key sort buffer) "FIXME: Docstring" (declare (indent defun)) ;; I think it's reasonable to use `eval' here. @@ -102,13 +112,22 @@ When nil, buffers are widened before being searched." (cond ((bound-and-true-p org-super-agenda-mode) (org-super-agenda--group-items it)) (t it)) (s-join "\n" it))) - (target-buffer (get-buffer-create "test-agenda-ng")) (inhibit-read-only t)) - (with-current-buffer target-buffer + (with-current-buffer (org-agenda-ng--buffer buffer) (erase-buffer) (insert entries) (pop-to-buffer (current-buffer)) - (org-agenda-finalize)))) + (org-agenda-finalize) + (goto-char (point-min))))) + +(defun org-agenda-ng--buffer (&optional name) + "Return Agenda NG buffer, creating it if necessary. +If NAME is non-nil, return buffer by that name instead of using +default buffer." + (with-current-buffer (get-buffer-create (or name org-agenda-ng-buffer-name)) + (unless (eq major-mode 'org-agenda-mode) + (org-agenda-mode)) + (current-buffer))) (defun org-agenda-ng--format-relative-date (difference) "Return relative date string for DIFFERENCE.