From 5574f33682a417786c9f6cbf80d5cfe29e68c104 Mon Sep 17 00:00:00 2001 From: Adam Porter Date: Wed, 11 Sep 2019 21:59:39 -0500 Subject: [PATCH] Change: (regexp) Match all regexps This seems more useful, because it makes it easier to narrow down results, which is the most common way to search. --- README.org | 3 ++- org-ql.el | 12 ++++++------ tests/test-org-ql.el | 10 +++++----- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/README.org b/README.org index 180bf2c..0c32e91 100644 --- a/README.org +++ b/README.org @@ -228,7 +228,7 @@ Arguments are listed next to predicate names, where applicable. + =path (&rest regexps)= :: Return non-nil if current heading's buffer's filename path matches any of =REGEXPS= (regexp strings). Without arguments, return non-nil if buffer is file-backed. + ~priority (&optional comparator-or-priority priority)~ :: Return non-nil if current heading has a certain priority. ~COMPARATOR-OR-PRIORITY~ should be either a comparator function, like ~<=~, or a priority string, like "A" (in which case (~=~ will be the comparator). If ~COMPARATOR-OR-PRIORITY~ is a comparator, ~PRIORITY~ should be a priority string. If both arguments are nil, return non-nil if heading has any defined priority. + ~property (property &optional value)~ :: Return non-nil if current entry has ~PROPERTY~ (a string), and optionally ~VALUE~ (a string). Note that property inheritance is currently /not/ enabled for this predicate. If you need to test with inheritance, you could use a custom predicate form, like ~(org-entry-get (point) "PROPERTY" 'inherit)~. -+ ~regexp (regexp)~ :: Return non-nil if current entry matches ~REGEXP~ (a regexp string). Matches against entire entry, from beginning of its heading to the next heading. ++ ~regexp (&rest regexps)~ :: Return non-nil if current entry matches all of ~REGEXPS~ (regexp strings). Matches against entire entry, from beginning of its heading to the next heading. + ~tags (&optional tags)~ :: Return non-nil if current heading has one or more of ~TAGS~ (a list of strings). Tests both inherited and local tags. + =tags-inherited (&optional tags)= :: Return non-nil if current heading's inherited tags include one or more of =TAGS= (a list of strings). If TAGS is nil, return non-nil if heading has any inherited tags. - Aliases: =inherited-tags=, =tags-i=, =itags=. @@ -486,6 +486,7 @@ Expands into a call to ~org-ql-select~ with the same arguments. For convenience *Changed* + Predicate =heading= now accepts multiple regexps, which are matched with boolean =AND=. ++ Predicate =regexp= now matches its regexp arguments with boolean =AND=. ** 0.2.1 diff --git a/org-ql.el b/org-ql.el index b4d3db2..a80a9d9 100644 --- a/org-ql.el +++ b/org-ql.el @@ -427,9 +427,9 @@ replace the clause with a preamble." ;; Return element, because the predicate still needs testing. element) (`(regexp . ,regexps) - (setq org-ql-preamble (s-join "\\|" regexps)) - ;; Return nil, because we don't need to test the predicate. - nil) + ;; Search for first regexp, then confirm with predicate. + (setq org-ql-preamble (car regexps)) + element) (`(todo . ,(and todo-keywords (guard todo-keywords))) ;; FIXME: With case-folding, a query like (todo "WAITING") can find a ;; non-todo heading named "Waiting". For correctness, we could test the @@ -910,15 +910,15 @@ priority." (org-is-habit-p)) (org-ql--defpred regexp (&rest regexps) - "Return non-nil if current entry matches one of REGEXPS (regexp strings)." + "Return non-nil if current entry matches all of REGEXPS (regexp strings)." (let ((end (or (save-excursion (outline-next-heading)) (point-max)))) (save-excursion (goto-char (line-beginning-position)) (cl-loop for regexp in regexps - thereis (save-excursion - (re-search-forward regexp end t)))))) + always (save-excursion + (re-search-forward regexp end t)))))) (org-ql--defpred heading (&rest regexps) "Return non-nil if current entry's heading matches all REGEXPS (regexp strings)." diff --git a/tests/test-org-ql.el b/tests/test-org-ql.el index f0d0286..11ee176 100644 --- a/tests/test-org-ql.el +++ b/tests/test-org-ql.el @@ -512,19 +512,19 @@ RESULTS should be a list of strings as returned by '("Take over the universe" "Take over the world" "Take over Mars" "Take over the moon" "Get haircut"))) (org-ql-it "with 2 arguments" - (org-ql-expect ((regexp "Take over" "pizza") + (org-ql-expect ((regexp "Take over" "universe") :sort todo) - '("Take over the universe" "Take over the world" "Take over Mars" "Take over the moon" "Order a pizza" "Get haircut"))) + '("Take over the universe"))) (org-ql-it "with a plain string" (org-ql-expect ("Take over" :sort todo) '("Take over the universe" "Take over the world" "Take over Mars" "Take over the moon" "Get haircut"))) - (org-ql-it "with two plain strings" - (org-ql-expect ((or "Take over" "pizza") + (org-ql-it "with two plain strings in an OR" + (org-ql-expect ((or "Take over" "universe") :sort todo) - '("Take over the universe" "Take over the world" "Take over Mars" "Take over the moon" "Order a pizza" "Get haircut")))) + '("Take over the universe" "Take over the world" "Take over Mars" "Take over the moon" "Get haircut")))) (describe "(scheduled)"