From f97a13a130ecd6b1d5a349fbb146ef2860c1dbf0 Mon Sep 17 00:00:00 2001 From: Tommy Jollyboat <11634808+ComedyTomedy@users.noreply.github.com> Date: Fri, 11 Oct 2024 00:19:29 +0100 Subject: [PATCH 1/2] Feat: Enable all valid priority values Expand recognised priority values from A-C to current org-mode standard of A-Z and 0-64. --- org-ql.el | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/org-ql.el b/org-ql.el index 76af6fc..5edb2b3 100644 --- a/org-ql.el +++ b/org-ql.el @@ -1735,29 +1735,28 @@ priority B)." `(priority ',comparator ,letter))) :preambles - (;; NOTE: This only accepts A, B, or C. I haven't seen - ;; other priorities in the wild, so this will do for now. - (`(,predicate-names) + ((`(,predicate-names) ;; Any priority cookie. - (list :regexp (rx-to-string `(seq bol (1+ "*") (1+ blank) (0+ nonl) "[#" (in "ABC") "]") t))) + (list :regexp (rx-to-string `(seq bol (1+ "*") (1+ blank) (0+ nonl) "[#" (or (in "A-Z") (1+ (in "0-9"))) "]") t))) (`(,predicate-names ,(and (or ''= ''< ''> ''<= ''>=) comparator) ,letter) ;; Comparator and priority letter. ;; NOTE: The double-quoted comparators. See below. - (let* ((priority-letters '("A" "B" "C")) + (let* ((priority-letters (append (mapcar #'number-to-string (number-sequence 0 64)) + (mapcar #'string (number-sequence ?A ?Z)))) (index (-elem-index letter priority-letters)) ;; NOTE: Higher priority == lower number. ;; NOTE: Because we need to support both preamble-based queries and ;; regular predicate ones, we work around an idiosyncrasy of query ;; pre-processing by accepting both quoted and double-quoted comparator ;; function symbols. Not the most elegant solution, but it works. - (priorities (s-join "" (pcase comparator - ((or '= ''=) (list letter)) - ((or '> ''>) (cl-subseq priority-letters 0 index)) - ((or '>= ''>=) (cl-subseq priority-letters 0 (1+ index))) - ((or '< ''<) (cl-subseq priority-letters (1+ index))) - ((or '<= ''<=) (cl-subseq priority-letters index)))))) + (priorities (pcase comparator + ((or '= ''=) (list letter)) + ((or '> ''>) (cl-subseq priority-letters 0 index)) + ((or '>= ''>=) (cl-subseq priority-letters 0 (1+ index))) + ((or '< ''<) (cl-subseq priority-letters (1+ index))) + ((or '<= ''<=) (cl-subseq priority-letters index))))) (list :regexp (rx-to-string `(seq bol (1+ "*") (1+ blank) (optional (1+ upper) (1+ blank)) - "[#" (in ,priorities) "]") t)))) + "[#" (or ,@priorities) "]") t)))) (`(,predicate-names . ,letters) ;; One or more priorities. ;; MAYBE: Disable case-folding. @@ -1780,11 +1779,11 @@ priority B)." (`(,(and (or '= '< '> '<= '>=) comparator) ,priority-arg) ;; Comparator and priority arguments given: compare item priority using them. (funcall comparator item-priority - (* 1000 (- org-lowest-priority (string-to-char priority-arg))))) + (org-get-priority (format "[#%s]" priority-arg)))) (_ ;; List of priorities given as arguments: compare each of them to item priority using =. (cl-loop for priority-arg in args - thereis (= item-priority (* 1000 (- org-lowest-priority (string-to-char priority-arg))))))))) + thereis (= item-priority (org-get-priority (format "[#%s]" priority-arg)))))))) (org-ql-defpred property (property &optional value &key inherit) "Return non-nil if current entry has PROPERTY, and optionally VALUE. @@ -2501,11 +2500,20 @@ A and B are Org timestamp elements." (a-ts t) (b-ts nil))))) +(defun org-ql--priority-to-value (el) + "Return an integer suitable for sorting priorities." + (let ((prio (org-element-property :priority el))) + (cond + ((not prio) (org-priority-to-value (org-element-property :raw-value el))) + ((not (integerp prio)) nil) + ((<= ?0 prio ?9) (- prio ?0)) + (t prio)))) + (defun org-ql--priority< (a b) "Return non-nil if A's priority is higher than B's. A and B are Org headline elements." (cl-macrolet ((priority (item) - `(org-element-property :priority ,item))) + `(org-ql--priority-to-value ,item))) ;; NOTE: Priorities are numbers in Org elements. This might differ from the priority selector logic. (let ((a-priority (priority a)) (b-priority (priority b))) From c847f88b98dd1de8d0cc82f43bb963088a757921 Mon Sep 17 00:00:00 2001 From: Tommy Jollyboat <11634808+ComedyTomedy@users.noreply.github.com> Date: Sat, 12 Oct 2024 11:49:42 +0100 Subject: [PATCH 2/2] Test: Add tests for numerical priorities --- tests/data.org | 6 +++--- tests/test-org-ql.el | 12 +++++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/tests/data.org b/tests/data.org index ec42ce9..b138651 100644 --- a/tests/data.org +++ b/tests/data.org @@ -62,12 +62,12 @@ SCHEDULED: <2017-07-05 Wed 18:00> :Effort: 5 :END: -* TODO [#C] Get haircut :personal:@town: +* TODO [#Z] Get haircut :personal:@town: SCHEDULED: <2017-07-05 Wed> Should probably do this before I take over the world. Want to look my best. (Not that it will matter once I'm in charge.) -* TODO [#B] Internet :bills: +* TODO [#1] Internet :bills: DEADLINE: <2017-07-21 Fri -1m> * TODO [#A] Spaceship lease :bills:spaceship: @@ -76,7 +76,7 @@ DEADLINE: <2017-08-01 Tue -1m> :agenda-group: bills :END: -* TODO [#B] Fix flux capacitor :spaceship:shopping:@computer: +* TODO [#9] Fix flux capacitor :spaceship:shopping:@computer: SCHEDULED: <2017-07-05 Wed> If I don't, the frobnicator will probably fall off halfway to Mars... diff --git a/tests/test-org-ql.el b/tests/test-org-ql.el index 923ec66..d6c80d1 100644 --- a/tests/test-org-ql.el +++ b/tests/test-org-ql.el @@ -1324,13 +1324,19 @@ with keyword arg NOW in PLIST." '("Take over the moon" "Get haircut"))) (org-ql-it "<= a priority" (org-ql-expect ('(priority <= "B")) - '("Take over Mars" "Take over the moon" "Renew membership in supervillain club" "Learn universal sign language" "Get haircut" "Internet" "Fix flux capacitor"))) + '("Take over Mars" "Take over the moon" "Renew membership in supervillain club" "Learn universal sign language" "Get haircut"))) (org-ql-it "> a priority" (org-ql-expect ('(priority > "B")) - '("Take over the universe" "Take over the world" "Skype with president of Antarctica" "Spaceship lease"))) + '("Take over the universe" "Take over the world" "Skype with president of Antarctica" "Internet" "Spaceship lease" "Fix flux capacitor"))) (org-ql-it ">= a priority" (org-ql-expect ('(priority >= "B")) - '("Take over the universe" "Take over the world" "Skype with president of Antarctica" "Take over Mars" "Renew membership in supervillain club" "Learn universal sign language" "Internet" "Spaceship lease" "Fix flux capacitor")))) + '("Take over the universe" "Take over the world" "Skype with president of Antarctica" "Take over Mars" "Renew membership in supervillain club" "Learn universal sign language" "Internet" "Spaceship lease" "Fix flux capacitor"))) + (org-ql-it "compare numerical priorities" + (org-ql-expect ('(priority > "5")) + '("Internet"))) + (org-ql-it "compare double-digit numerical priorities" + (org-ql-expect ('(priority > "60")) + '("Internet" "Fix flux capacitor")))) (describe "(property)"