diff --git a/README.org b/README.org index a12c93f..cc371be 100644 --- a/README.org +++ b/README.org @@ -59,11 +59,11 @@ More examples are available in [[examples.org]]. The functionality provided may be grouped by: + Interactive commands :: ~org-ql-search~ -+ Non-interactive functions and macros :: ~org-ql~ (macro), ~org-ql-select~ (function), ~org-ql-query~ (function), and ~org-ql-agenda~ (macro) ++ Non-interactive functions and macros :: ~org-ql~ (macro), ~org-ql-select~ (function), ~org-ql-query~ (function), ~org-ql-block~ (agenda function), and ~org-ql-agenda~ (macro) Alternatively, they may be grouped by: -+ Showing an agenda-like view :: ~org-ql-search~ (command), and ~org-ql-agenda~ (macro) ++ Showing an agenda-like view :: ~org-ql-search~ (command), ~org-ql-block~ (agenda function), and ~org-ql-agenda~ (macro) + Returning a list of matches or acting on them :: ~org-ql~ (macro), ~org-ql-select~ (function), and ~org-ql-query~ (function) Feedback on these APIs is welcome. Eventually, after being tested and polished, they will be considered stable. @@ -141,6 +141,30 @@ Arguments are listed next to predicate names, where applicable. *** Agenda-like views +**** Function: ~org-ql-block~ + +For use as a custom agenda block type in ~org-agenda-custom-commands~. For example, you could define a custom series command like this, which would list all priority A items tagged =Emacs= with to-do keyword =SOMEDAY=, followed by the standard agenda view, in a single buffer: + +#+BEGIN_SRC elisp + (setq org-agenda-custom-commands + '(("ces" "Custom: Agenda and Emacs SOMEDAY [#A] items" + ((org-ql-block '(and (todo "SOMEDAY") + (tags "Emacs") + (priority "A"))) + (agenda))))) +#+END_SRC + +Which would be equivalent to a ~tags-todo~ search like this: + +#+BEGIN_SRC elisp + (setq org-agenda-custom-commands + '(("ces" "Custom: Agenda and Emacs SOMEDAY [#A] items" + ((tags-todo "PRIORITY=\"A\"+Emacs/!SOMEDAY") + (agenda))))) +#+END_SRC + +However, the ~org-ql-block~ version runs in about 1/5th the time. + **** Macro: ~org-ql-agenda~ This macro is like ~org-ql~, but it presents matching entries in an Agenda-like view. It's compatible with [[https://github.com/alphapapa/org-super-agenda][org-super-agenda]], which provides grouping. For example: @@ -314,6 +338,7 @@ Expands into a call to ~org-ql-select~ with the same arguments. For convenience + Bare strings like ~"string"~ can be used in queries, which are converted to ~(regexp "string")~ automatically. + Selector ~(regexp)~ accepts multiple regexps to test. + Macro ~org-ql~ and functions ~org-ql-query~ and ~org-ql-select~ now also accept a comparator function in their ~:sort~ argument. ++ Function ~org-ql-block~, which works as an Org Agenda series/composite/block command, usable in custom agenda commands defined in variable ~org-agenda-custom-commands~. (Inspired by [[https://github.com/pestctrl/emacs-config/blob/84c557982a860e86d6f67976a82ea776a7bd2c7a/config-org-new.org#my-own-agenda-renderer][Benson Chu's config]].) *Changed* + Function ~org-ql-query~ renamed to ~org-ql-select~. ~org-ql-query~ now refers to a new function. diff --git a/org-ql-agenda.el b/org-ql-agenda.el index 1bdcb6e..227ea7d 100644 --- a/org-ql-agenda.el +++ b/org-ql-agenda.el @@ -241,6 +241,33 @@ SORT: One or a list of `org-ql' sorting functions, like `date' or (org-agenda-finalize) (goto-char (point-min))))) +(defun org-ql-agenda-block (query) + "Insert items for QUERY into current buffer. +QUERY should be an `org-ql' query form. Like other agenda block +commands, it searches files returned by function +`org-agenda-files'. Intended to be used as a user-defined +function in `org-agenda-custom-commands'. QUERY corresponds to +the `match' item in the custom command form." + (when-let* ((from (org-agenda-files nil 'ifmode)) + (items (org-ql-select from + query :action 'element-with-markers))) + ;; Not sure if calling the prepare function is necessary, but let's follow the pattern. + (org-agenda-prepare) + ;; FIXME: `org-agenda--insert-overriding-header' is from an Org version newer than + ;; I'm using. Should probably declare it as a minimum Org version after upgrading. + ;; (org-agenda--insert-overriding-header (org-ql-agenda--header-line-format from query)) + (insert (org-add-props (org-ql-agenda--header-line-format from query) + nil 'face 'org-agenda-structure) "\n") + ;; Calling `org-agenda-finalize' should be unnecessary, because in a "series" agenda, + ;; `org-agenda-multi' is bound non-nil, in which case `org-agenda-finalize' does nothing. + ;; But we do call `org-agenda-finalize-entries', which allows `org-super-agenda' to work. + (->> items + (-map #'org-ql-agenda--format-element) + org-agenda-finalize-entries + insert))) + +(defalias 'org-ql-block 'org-ql-agenda-block) + (defun org-ql-agenda--header-line-format (buffers-files query) "Return header-line-format for BUFFERS-FILES and QUERY." (let* ((query-formatted (format "%S" query))