Add: org-ql-block

Usable as an Org Agenda custom command block type.  Inspired by
@pestctrl's custom config:

84c557982a/config-org-new.org (my-own-agenda-renderer)
This commit is contained in:
Adam Porter 2019-08-08 09:34:05 -05:00
parent d37f7c3eea
commit bd56652c66
2 changed files with 54 additions and 2 deletions

View file

@ -59,11 +59,11 @@ More examples are available in [[examples.org]].
The functionality provided may be grouped by: The functionality provided may be grouped by:
+ Interactive commands :: ~org-ql-search~ + 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: 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) + 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. 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 *** 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~ **** 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: 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. + Bare strings like ~"string"~ can be used in queries, which are converted to ~(regexp "string")~ automatically.
+ Selector ~(regexp)~ accepts multiple regexps to test. + 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. + 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* *Changed*
+ Function ~org-ql-query~ renamed to ~org-ql-select~. ~org-ql-query~ now refers to a new function. + Function ~org-ql-query~ renamed to ~org-ql-select~. ~org-ql-query~ now refers to a new function.

View file

@ -241,6 +241,33 @@ SORT: One or a list of `org-ql' sorting functions, like `date' or
(org-agenda-finalize) (org-agenda-finalize)
(goto-char (point-min))))) (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) (defun org-ql-agenda--header-line-format (buffers-files query)
"Return header-line-format for BUFFERS-FILES and QUERY." "Return header-line-format for BUFFERS-FILES and QUERY."
(let* ((query-formatted (format "%S" query)) (let* ((query-formatted (format "%S" query))