Merge: parent-ancestors-predicates

Closes #77.  Thanks to Josh Moller-Mara (@mm--).
This commit is contained in:
Adam Porter 2020-01-22 23:35:02 -06:00
commit d1a84a7c28
6 changed files with 277 additions and 106 deletions

View file

@ -60,9 +60,16 @@ Installing with [[https://framagit.org/steckerhalter/quelpa][Quelpa]] is easy:
#+END_SRC #+END_SRC
* Usage * Usage
:PROPERTIES:
:TOC: :include descendants :depth 1
:END:
:CONTENTS: :CONTENTS:
- [[#commands][Commands]] - [[#commands][Commands]]
- [[#queries][Queries]] - [[#queries][Queries]]
- [[#non-sexp-query-syntax][Non-sexp query syntax]]
- [[#general-predicates][General predicates]]
- [[#ancestordescendant-predicates][Ancestor/descendant predicates]]
- [[#datetime-predicates][Date/time predicates]]
- [[#functions--macros][Functions / Macros]] - [[#functions--macros][Functions / Macros]]
:END: :END:
@ -143,9 +150,13 @@ Show a sparse tree for ~QUERY~ in ~BUFFER~ and return number of results. The tr
~QUERY~ is an ~org-ql~ query sexp (quoted, since this is a function). ~BUFFER~ defaults to the current buffer. When ~KEEP-PREVIOUS~ is non-nil (interactively, with prefix), the outline is not reset to the overview state before finding matches, which allows stacking calls to this command. Runs ~org-occur-hook~ after making the sparse tree. ~QUERY~ is an ~org-ql~ query sexp (quoted, since this is a function). ~BUFFER~ defaults to the current buffer. When ~KEEP-PREVIOUS~ is non-nil (interactively, with prefix), the outline is not reset to the overview state before finding matches, which allows stacking calls to this command. Runs ~org-occur-hook~ after making the sparse tree.
** Queries ** Queries
:PROPERTIES:
:TOC: :include descendants :depth 1
:END:
:CONTENTS: :CONTENTS:
- [[#non-sexp-query-syntax][Non-sexp query syntax]] - [[#non-sexp-query-syntax][Non-sexp query syntax]]
- [[#predicates][Predicates]] - [[#general-predicates][General predicates]]
- [[#ancestordescendant-predicates][Ancestor/descendant predicates]]
- [[#datetime-predicates][Date/time predicates]] - [[#datetime-predicates][Date/time predicates]]
:END: :END:
@ -175,13 +186,11 @@ The command =org-ql-search= also accepts, and the command =helm-org-ql= only acc
Note that the =priority= predicate does not support comparators in the non-sexp syntax, so multiple priorities should be passed instead, as seen in the last example. Note that the =priority= predicate does not support comparators in the non-sexp syntax, so multiple priorities should be passed instead, as seen in the last example.
*** Predicates *** General predicates
Arguments are listed next to predicate names, where applicable. Arguments are listed next to predicate names, where applicable.
+ =category (&optional categories)= :: Return non-nil if current heading is in one or more of ~CATEGORIES~ (a list of strings). + =category (&optional categories)= :: Return non-nil if current heading is in one or more of ~CATEGORIES~ (a list of strings).
+ =children (&optional query)= :: Return non-nil if current heading has direct child headings. If ~QUERY~, test it against child headings. This selector may be nested, e.g. to match grandchild headings.
+ =descendants (&optional query)= :: Return non-nil if current heading has descendant headings. If ~QUERY~, test it against descendant headings. This selector may be nested (if you can grok the nesting!).
+ =done= :: Return non-nil if entry's ~TODO~ keyword is in ~org-done-keywords~. + =done= :: Return non-nil if entry's ~TODO~ keyword is in ~org-done-keywords~.
+ =habit= :: Return non-nil if entry is a habit. + =habit= :: Return non-nil if entry is a habit.
+ =heading (&rest regexps)= :: Return non-nil if current entry's heading matches all ~REGEXPS~ (regexp strings). + =heading (&rest regexps)= :: Return non-nil if current entry's heading matches all ~REGEXPS~ (regexp strings).
@ -206,6 +215,13 @@ Arguments are listed next to predicate names, where applicable.
- Aliases: ~tags&~. - Aliases: ~tags&~.
+ =todo (&optional keywords)= :: Return non-nil if current heading is a ~TODO~ item. With ~KEYWORDS~, return non-nil if its keyword is one of ~KEYWORDS~ (a list of strings). When called without arguments, only matches non-done tasks (i.e. does not match keywords in ~org-done-keywords~). + =todo (&optional keywords)= :: Return non-nil if current heading is a ~TODO~ item. With ~KEYWORDS~, return non-nil if its keyword is one of ~KEYWORDS~ (a list of strings). When called without arguments, only matches non-done tasks (i.e. does not match keywords in ~org-done-keywords~).
*** Ancestor/descendant predicates
+ =ancestors (&optional query)= :: Return non-nil if current heading has ancestor headings. If ~QUERY~, return non-nil if an ancestor heading matches it. This selector may be nested.
+ =children (&optional query)= :: Return non-nil if current heading has direct child headings. If ~QUERY~, return non-nil if a child heading matches it. This selector may be nested, e.g. to match grandchild headings.
+ =descendants (&optional query)= :: Return non-nil if current heading has descendant headings. If ~QUERY~, return non-nil if a descendant heading matches it. This selector may be nested (if you can grok the nesting!).
+ =parent (&optional query)= :: Return non-nil if current heading has a direct parent heading. If ~QUERY~, return non-nil if the parent heading matches it. This selector may be nested, e.g. to match grandparent headings.
*** Date/time predicates *** Date/time predicates
All of these predicates take optional keyword arguments ~:from~, ~:to:~, and ~:on~: All of these predicates take optional keyword arguments ~:from~, ~:to:~, and ~:on~:
@ -395,6 +411,7 @@ Expands into a call to ~org-ql-select~ with the same arguments. For convenience
- Negation of terms in plain queries using ~!~. For example, ~tags:space !moon~ to exclude entries which contain ~moon~. - Negation of terms in plain queries using ~!~. For example, ~tags:space !moon~ to exclude entries which contain ~moon~.
- Predicates =outline-path= (alias =olp=) and =outline-path-segment= (alias =olps=). - Predicates =outline-path= (alias =olp=) and =outline-path-segment= (alias =olps=).
- Predicate ~src~, which matches Org Babel source blocks. - Predicate ~src~, which matches Org Babel source blocks.
- Predicates =parent= and =ancestors=. (Thanks to [[https://github.com/mm--][Josh Moller-Mara]].)
- Alias =h= for =heading= predicate. - Alias =h= for =heading= predicate.
- Alias =r= for =regexp= predicate. (Thanks to [[https://github.com/tumashu][Feng Shu]].) - Alias =r= for =regexp= predicate. (Thanks to [[https://github.com/tumashu][Feng Shu]].)
+ Info manual. + Info manual.
@ -403,6 +420,7 @@ Expands into a call to ~org-ql-select~ with the same arguments. For convenience
+ Respect Org Agenda restriction in =org-ql-block=. (Thanks to [[https://github.com/yantar92][Ihor Radchenko]] for reporting.) + Respect Org Agenda restriction in =org-ql-block=. (Thanks to [[https://github.com/yantar92][Ihor Radchenko]] for reporting.)
+ Option =org-ql-view-sidebar-sort-views=. + Option =org-ql-view-sidebar-sort-views=.
+ Mouseover =help-echo= text for =org-ql-views= default view names. + Mouseover =help-echo= text for =org-ql-views= default view names.
+ "Dangling tasks" default view in =org-ql-views=. (Users who have modified =org-ql-views= from the default will not see the new view unless they copy it into their config.)
*Changed* *Changed*
+ Some default =org-ql-view= views (users who have modified =org-ql-views= from the default will not see the new views unless they copy them into their config): + Some default =org-ql-view= views (users who have modified =org-ql-views= from the default will not see the new views unless they copy them into their config):

View file

@ -2,17 +2,20 @@
* Contents * Contents
:PROPERTIES: :PROPERTIES:
:TOC: this :TOC: :include siblings :ignore this
:END:
:CONTENTS:
- [[#agenda-like-view][Agenda-like view]]
- [[#entries-from-the-past-week][Entries from the past week]]
- [[#find-entries-matching-a-certain-custom_id][Find entries matching a certain CUSTOM_ID]]
- [[#listing-bills-coming-due][Listing bills coming due]]
- [[#music-database][Music database]]
- [[#return-org-elements][Return Org elements]]
- [[#set-tags-on-certain-entries][Set tags on certain entries]]
- [[#show-entries-with-recent-timestamps][Show entries with recent timestamps]]
- [[#stuck-projects-block-agenda][Stuck projects block agenda]]
- [[#subproject-and-subtask-queries][Subproject and subtask queries]]
:END: :END:
- [[#agenda-like-view][Agenda-like view]]
- [[#entries-from-the-past-week][Entries from the past week]]
- [[#find-entries-matching-a-certain-custom_id][Find entries matching a certain CUSTOM_ID]]
- [[#listing-bills-coming-due][Listing bills coming due]]
- [[#music-database][Music database]]
- [[#return-org-elements][Return Org elements]]
- [[#set-tags-on-certain-entries][Set tags on certain entries]]
- [[#show-entries-with-recent-timestamps][Show entries with recent timestamps]]
- [[#stuck-projects-block-agenda][Stuck projects block agenda]]
* Agenda-like view * Agenda-like view
@ -173,9 +176,67 @@ With this =org-ql-block= agenda view, like:
((org-ql-block-header "Stuck Projects"))))))) ((org-ql-block-header "Stuck Projects")))))))
#+END_SRC #+END_SRC
* Subproject and subtask queries
#+BEGIN_SRC elisp
;; Search for subprojects.
(org-ql-search (org-agenda-files)
'(and (todo "PROJECT")
(ancestors (todo "PROJECT"))))
;; Search for all subtasks of projects, grouped by parent heading.
(org-ql-search (org-agenda-files)
'(and (todo)
(ancestors (todo "PROJECT")))
:super-groups '((:auto-parent t)))
;; Search for direct top-level tasks of projects.
(org-ql-search (org-agenda-files)
'(and (todo)
(parent (todo "PROJECT")))
:super-groups '((:auto-parent t)))
#+END_SRC
Of course, all of those presume using a =PROJECT= keyword to define projects. If one defines a project as any task which has an ancestor task, one could use queries like:
#+BEGIN_SRC elisp
;; Search for all subtasks of top-level projects, grouped by parent heading.
(org-ql-search (org-agenda-files)
'(and (todo)
(ancestors
(and (todo)
(not (parent)))))
:super-groups '((:auto-parent t)))
;; Search for all subtasks of all projects, including subprojects, grouped by project.
(org-ql-search (org-agenda-files)
'(and (todo)
(ancestors (todo)))
:super-groups '((:auto-parent t)))
#+END_SRC
Other interesting queries:
#+BEGIN_SRC elisp
;; Subtasks of upcoming deadline items.
(org-ql-search (org-agenda-files)
'(and (todo)
(ancestors
(and (not (done))
(deadline auto))))
:super-groups '((:auto-parent t)))
;; TODO items whose ancestor is already DONE, and should therefore be
;; either marked DONE or CANCELLED.
(org-ql-search (org-agenda-files)
'(and (todo)
(ancestors (done)))
:super-groups '((:auto-parent t)))
#+END_SRC
* COMMENT Code :noexport: * COMMENT Code :noexport:
:PROPERTIES: :PROPERTIES:
:TOC: ignore :TOC: :ignore (this descendants)
:END: :END:
** File-local variables ** File-local variables

View file

@ -177,6 +177,15 @@ See info node `(elisp)Cyclic Window Ordering'."
:super-groups 'org-super-agenda-groups :super-groups 'org-super-agenda-groups
:sort '(priority))))) :sort '(priority)))))
(cons "Review: Recently timestamped" #'org-ql-view-recent-items) (cons "Review: Recently timestamped" #'org-ql-view-recent-items)
(cons (propertize "Review: Dangling tasks"
'help-echo "Tasks whose ancestor is done")
(list :buffers-files #'org-agenda-files
:query '(and (todo)
(ancestors (done)))
:title (propertize "Review: Dangling tasks"
'help-echo "Tasks whose ancestor is done")
:sort '(date priority todo)
:super-groups '((:auto-parent t))))
(cons (propertize "Review: Stale tasks" (cons (propertize "Review: Stale tasks"
'help-echo "Tasks without a timestamp in the past 2 weeks") 'help-echo "Tasks without a timestamp in the past 2 weeks")
(list :buffers-files #'org-agenda-files (list :buffers-files #'org-agenda-files

111
org-ql.el
View file

@ -548,6 +548,10 @@ Replaces bare strings with (regexp) selectors, and appropriate
(`(children) '(children (lambda () t))) (`(children) '(children (lambda () t)))
(`(descendants ,query) `(descendants ',query)) (`(descendants ,query) `(descendants ',query))
(`(descendants) '(descendants (lambda () t))) (`(descendants) '(descendants (lambda () t)))
(`(parent ,query) `(parent ,(org-ql--query-predicate (rec query))))
(`(parent) '(parent (lambda () t)))
(`(ancestors ,query) `(ancestors ,(org-ql--query-predicate (rec query))))
(`(ancestors) '(ancestors (lambda () t)))
;; Timestamp-based predicates. I think this is the way that makes the most sense: ;; Timestamp-based predicates. I think this is the way that makes the most sense:
;; set the limit to N days in the future, adjusted to 23:59:59 (since Org doesn't ;; set the limit to N days in the future, adjusted to 23:59:59 (since Org doesn't
;; support timestamps down to the second, anyway, there should be no need to adjust ;; support timestamps down to the second, anyway, there should be no need to adjust
@ -929,41 +933,6 @@ Arguments STRING, POS, FILL, and LEVEL are according to
;;;;; Predicates ;;;;; Predicates
(org-ql--defpred children (query)
"Return non-nil if current entry has children matching QUERY."
(save-excursion
(save-restriction
(org-narrow-to-subtree)
(when (org-goto-first-child)
;; Lisp makes this easy and elegant: all we do is modify the query,
;; nesting it inside an (and), and it doesn't descend into grandchildren.
(let* ((level (org-current-level))
(query (cl-typecase query
(byte-code-function `(and (level ,level)
(funcall ,query)))
(t `(and (level ,level)
,query)))))
(catch 'found
(org-ql-select (current-buffer)
query
:narrow t
:action (lambda ()
(throw 'found t)))))))))
(org-ql--defpred descendants (query)
"Return non-nil if current entry has descendants matching QUERY."
(save-excursion
(save-restriction
(org-narrow-to-subtree)
(when (org-goto-first-child)
(narrow-to-region (point) (point-max))
(catch 'found
(org-ql-select (current-buffer)
query
:narrow t
:action (lambda ()
(throw 'found t))))))))
(org-ql--defpred category (&rest categories) (org-ql--defpred category (&rest categories)
"Return non-nil if current heading is in one or more of CATEGORIES (a list of strings)." "Return non-nil if current heading is in one or more of CATEGORIES (a list of strings)."
(when-let ((category (org-get-category (point)))) (when-let ((category (org-get-category (point))))
@ -1193,6 +1162,78 @@ language."
;; No regexps to check: return non-nil. ;; No regexps to check: return non-nil.
t)))))) t))))))
;;;;;; Ancestor/descendant
;; These predicates search ancestor and descendant headings for sub-queries.
;; Note that the implementations of the upward-searching, ancestor/parent predicates differ
;; from that of the downward-searching, descendants/children predicates in that the former
;; take a predicate function as their argument and test it on each heading (the predicate
;; being created by the `--pre-process-query' function, which see), while the latter take an
;; `org-ql' query form as their argument and execute another `org-ql-select' query inside of
;; the currently running query. This "split" implementation seems like the most generally
;; efficient one, because searching descendants searches potentially many more headings than
;; searching ancestors, so executing a full query in that case can be faster due to use of
;; the "preambles" provided by running a full query. However, see note below.
;; NOTE: The ancestors and parent predicates' docstrings are developer-facing
;; rather than user-facing, since their arguments are predicates provided
;; automatically by `--pre-process-query'.
(org-ql--defpred ancestors (predicate)
"Return non-nil if any of current entry's ancestors satisfy PREDICATE."
(org-with-wide-buffer
(cl-loop while (org-up-heading-safe)
thereis (org-ql--value-at (point) predicate))))
(org-ql--defpred parent (predicate)
"Return non-nil if the current entry's parent satisfies PREDICATE."
(org-with-wide-buffer
(when (org-up-heading-safe)
(org-ql--value-at (point) predicate))))
;; MAYBE: The `children' and `descendants' predicates could probably be rewritten like
;; the `ancestors' predicate, which avoids calling `org-ql-select' recursively and its
;; associated overhead. However, that would preclude the use of preambles, so depending
;; on the Org file being searched and the sub-query, performance could be better or
;; worse. It should be benchmarked extensively before so changing the implementation.
(org-ql--defpred children (query)
"Return non-nil if current entry has children matching QUERY."
(org-with-wide-buffer
;; Widening is needed if inside an "ancestors" query
(org-narrow-to-subtree)
(when (org-goto-first-child)
;; Lisp makes this easy and elegant: all we do is modify the query,
;; nesting it inside an (and), and it doesn't descend into grandchildren.
(let* ((level (org-current-level))
(query (cl-typecase query
(byte-code-function `(and (level ,level)
(funcall ,query)))
(t `(and (level ,level)
,query)))))
(catch 'found
(org-ql-select (current-buffer)
query
:narrow t
:action (lambda ()
(throw 'found t))))))))
(org-ql--defpred descendants (query)
"Return non-nil if current entry has descendants matching QUERY."
;; TODO: This could probably be rewritten like the `ancestors' predicate,
;; which avoids calling `org-ql-select' recursively and its associated overhead.
(org-with-wide-buffer
(org-narrow-to-subtree)
(when (org-goto-first-child)
(narrow-to-region (point) (point-max))
(catch 'found
(org-ql-select (current-buffer)
query
:narrow t
:action (lambda ()
(throw 'found t)))))))
;;;;;; Timestamps ;;;;;; Timestamps
;; TODO: Remove the _on vars from these arg lists. I think they're not ;; TODO: Remove the _on vars from these arg lists. I think they're not

View file

@ -50,7 +50,8 @@ Commands
Queries Queries
* Non-sexp query syntax:: * Non-sexp query syntax::
* Predicates:: * General predicates::
* Ancestor/descendant predicates::
* Date/time predicates:: * Date/time predicates::
@ -146,7 +147,8 @@ File: README.info, Node: Usage, Next: Changelog, Prev: Installation, Up: Top
4 Usage 4 Usage
******* *******
• • • • •
• • • • •
Feedback on these APIs is welcome. Eventually, after being tested Feedback on these APIs is welcome. Eventually, after being tested
and polished, they will be considered stable. and polished, they will be considered stable.
@ -294,7 +296,7 @@ File: README.info, Node: Queries, Next: Functions / Macros, Prev: Commands,
4.2 Queries 4.2 Queries
=========== ===========
• • • • • •
An org-ql query is a lisp form which may contain arbitrary lisp An org-ql query is a lisp form which may contain arbitrary lisp
forms, as well as certain built-in predicates. It is byte-compiled into forms, as well as certain built-in predicates. It is byte-compiled into
a predicate function which is tested with point on each heading in an a predicate function which is tested with point on each heading in an
@ -311,11 +313,12 @@ Org buffer; when it returns non-nil, the heading matches the query.
* Menu: * Menu:
* Non-sexp query syntax:: * Non-sexp query syntax::
* Predicates:: * General predicates::
* Ancestor/descendant predicates::
* Date/time predicates:: * Date/time predicates::
 
File: README.info, Node: Non-sexp query syntax, Next: Predicates, Up: Queries File: README.info, Node: Non-sexp query syntax, Next: General predicates, Up: Queries
4.2.1 Non-sexp query syntax 4.2.1 Non-sexp query syntax
--------------------------- ---------------------------
@ -345,24 +348,16 @@ non-sexp syntax, so multiple priorities should be passed instead, as
seen in the last example. seen in the last example.
 
File: README.info, Node: Predicates, Next: Date/time predicates, Prev: Non-sexp query syntax, Up: Queries File: README.info, Node: General predicates, Next: Ancestor/descendant predicates, Prev: Non-sexp query syntax, Up: Queries
4.2.2 Predicates 4.2.2 General predicates
---------------- ------------------------
Arguments are listed next to predicate names, where applicable. Arguments are listed next to predicate names, where applicable.
category (&optional categories) category (&optional categories)
Return non-nil if current heading is in one or more of CATEGORIES Return non-nil if current heading is in one or more of CATEGORIES
(a list of strings). (a list of strings).
children (&optional query)
Return non-nil if current heading has direct child headings. If
QUERY, test it against child headings. This selector may be
nested, e.g. to match grandchild headings.
descendants (&optional query)
Return non-nil if current heading has descendant headings. If
QUERY, test it against descendant headings. This selector may be
nested (if you can grok the nesting!).
done done
Return non-nil if entrys TODO keyword is in org-done-keywords. Return non-nil if entrys TODO keyword is in org-done-keywords.
habit habit
@ -444,9 +439,32 @@ Arguments are listed next to predicate names, where applicable.
org-done-keywords). org-done-keywords).
 
File: README.info, Node: Date/time predicates, Prev: Predicates, Up: Queries File: README.info, Node: Ancestor/descendant predicates, Next: Date/time predicates, Prev: General predicates, Up: Queries
4.2.3 Date/time predicates 4.2.3 Ancestor/descendant predicates
------------------------------------
ancestors (&optional query)
Return non-nil if current heading has ancestor headings. If
QUERY, return non-nil if an ancestor heading matches it. This
selector may be nested.
children (&optional query)
Return non-nil if current heading has direct child headings. If
QUERY, return non-nil if a child heading matches it. This
selector may be nested, e.g. to match grandchild headings.
descendants (&optional query)
Return non-nil if current heading has descendant headings. If
QUERY, return non-nil if a descendant heading matches it. This
selector may be nested (if you can grok the nesting!).
parent (&optional query)
Return non-nil if current heading has a direct parent heading. If
QUERY, return non-nil if the parent heading matches it. This
selector may be nested, e.g. to match grandparent headings.

File: README.info, Node: Date/time predicates, Prev: Ancestor/descendant predicates, Up: Queries
4.2.4 Date/time predicates
-------------------------- --------------------------
All of these predicates take optional keyword arguments :from, :to:, All of these predicates take optional keyword arguments :from, :to:,
@ -722,6 +740,8 @@ will be pushed to the master branch when ready.
• Predicates outline-path (alias olp) and outline-path-segment • Predicates outline-path (alias olp) and outline-path-segment
(alias olps). (alias olps).
• Predicate src, which matches Org Babel source blocks. • Predicate src, which matches Org Babel source blocks.
• Predicates parent and ancestors. (Thanks to Josh Moller-Mara
(https://github.com/mm--).)
• Alias h for heading predicate. • Alias h for heading predicate.
• Alias r for regexp predicate. (Thanks to Feng Shu • Alias r for regexp predicate. (Thanks to Feng Shu
(https://github.com/tumashu).) (https://github.com/tumashu).)
@ -735,6 +755,9 @@ will be pushed to the master branch when ready.
Radchenko (https://github.com/yantar92) for reporting.) Radchenko (https://github.com/yantar92) for reporting.)
• Option org-ql-view-sidebar-sort-views. • Option org-ql-view-sidebar-sort-views.
• Mouseover help-echo text for org-ql-views default view names. • Mouseover help-echo text for org-ql-views default view names.
• "Dangling tasks" default view in org-ql-views. (Users who have
modified org-ql-views from the default will not see the new view
unless they copy it into their config.)
*Changed* *Changed*
• Some default org-ql-view views (users who have modified • Some default org-ql-view views (users who have modified
@ -1037,39 +1060,40 @@ GPLv3
 
Tag Table: Tag Table:
Node: Top225 Node: Top225
Node: Contents1367 Node: Contents1410
Node: Screenshots1541 Node: Screenshots1584
Node: Installation1659 Node: Installation1702
Node: Quelpa2297 Node: Quelpa2340
Node: Usage2740 Node: Usage2783
Node: Commands3064 Node: Commands3132
Node: org-ql-search3537 Node: org-ql-search3605
Node: helm-org-ql5185 Node: helm-org-ql5253
Node: org-ql-view5597 Node: org-ql-view5665
Node: org-ql-view-sidebar5795 Node: org-ql-view-sidebar5863
Node: org-ql-view-recent-items6151 Node: org-ql-view-recent-items6219
Node: org-ql-sparse-tree6635 Node: org-ql-sparse-tree6703
Node: Queries7435 Node: Queries7503
Node: Non-sexp query syntax8296 Node: Non-sexp query syntax8411
Node: Predicates9995 Node: General predicates10118
Node: Date/time predicates15217 Node: Ancestor/descendant predicates14925
Node: Functions / Macros17852 Node: Date/time predicates16053
Node: Agenda-like views18085 Node: Functions / Macros18708
Node: Listing / acting-on results19490 Node: Agenda-like views18941
Node: Changelog24092 Node: Listing / acting-on results20346
Node: 04-pre24629 Node: Changelog24948
Node: 03228251 Node: 04-pre25485
Node: 03128632 Node: 03229405
Node: 0328827 Node: 03129786
Node: 02331800 Node: 0329981
Node: 02232026 Node: 02332954
Node: 02132292 Node: 02233180
Node: 0232489 Node: 02133446
Node: 0136522 Node: 0233643
Node: Notes36621 Node: 0137676
Node: Comparison with Org Agenda searches36783 Node: Notes37775
Node: org-sidebar37654 Node: Comparison with Org Agenda searches37937
Node: License37933 Node: org-sidebar38808
Node: License39087
 
End Tag Table End Tag Table

View file

@ -347,6 +347,24 @@ RESULTS should be a list of strings as returned by
;; TODO: Other predicates. ;; TODO: Other predicates.
(describe "(ancestors)"
(org-ql-it "without sub-query"
(org-ql-expect ((ancestors))
'("Take over the world" "Skype with president of Antarctica" "Take over Mars" "Visit Mars" "Take over the moon" "Visit the moon" "Practice leaping tall buildings in a single bound" "Renew membership in supervillain club" "Learn universal sign language" "/r/emacs" "Shop for groceries" "Sunrise/sunset" "Rewrite Emacs in Common Lisp" "Write a symphony")))
(org-ql-it "with sub-query"
(org-ql-expect ((ancestors (heading "universe")))
'("Take over the world" "Skype with president of Antarctica" "Take over Mars" "Visit Mars" "Take over the moon" "Visit the moon" "Practice leaping tall buildings in a single bound" "Renew membership in supervillain club" "Learn universal sign language"))))
(describe "(parent)"
(org-ql-it "without sub-query"
(org-ql-expect ((parent))
'("Take over the world" "Skype with president of Antarctica" "Take over Mars" "Visit Mars" "Take over the moon" "Visit the moon" "Practice leaping tall buildings in a single bound" "Renew membership in supervillain club" "Learn universal sign language" "/r/emacs" "Shop for groceries" "Sunrise/sunset" "Rewrite Emacs in Common Lisp" "Write a symphony")))
(org-ql-it "with sub-query"
(org-ql-expect ((parent (and (todo) (priority "A"))))
'("Take over the world" "Skype with president of Antarctica" "Take over Mars" "Take over the moon" "Practice leaping tall buildings in a single bound" "Renew membership in supervillain club" "Learn universal sign language"))))
(describe "(category)" (describe "(category)"
(org-ql-it "without arguments" (org-ql-it "without arguments"