Add: (property) :multi argument
This commit is contained in:
parent
ac2d43588a
commit
5f54a2c653
2 changed files with 26 additions and 11 deletions
|
|
@ -242,7 +242,7 @@ Arguments are listed next to predicate names, where applicable.
|
||||||
- Aliases: ~olps~.
|
- Aliases: ~olps~.
|
||||||
+ =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.
|
+ =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 (&rest args)= :: Return non-nil if current heading has a certain priority. ~ARGS~ may be either a list of one or more priority letters as strings, or a comparator function symbol followed by a priority letter string. For example: ~(priority "A") (priority "A" "B") (priority '>= "B")~ Note that items without a priority cookie never match this predicate (while Org itself considers items without a cookie to have the default priority, which, by default, is equal to priority ~B~).
|
+ =priority (&rest args)= :: Return non-nil if current heading has a certain priority. ~ARGS~ may be either a list of one or more priority letters as strings, or a comparator function symbol followed by a priority letter string. For example: ~(priority "A") (priority "A" "B") (priority '>= "B")~ Note that items without a priority cookie never match this predicate (while Org itself considers items without a cookie to have the default priority, which, by default, is equal to priority ~B~).
|
||||||
+ =property (property &optional value &key inherit)= :: Return non-nil if current entry has ~PROPERTY~ (a string), and optionally ~VALUE~ (a string). If ~INHERIT~ is nil, only match entries with ~PROPERTY~ set on the entry; if t, also match entries with inheritance. If ~INHERIT~ is not specified, use the Boolean value of ~org-use-property-inheritance~, which see (i.e. it is only interpreted as nil or non-nil).
|
+ =property (property &optional value &key inherit multi)= :: Return non-nil if current entry has ~PROPERTY~ (a string), and optionally ~VALUE~ (a string). If ~INHERIT~ is nil, only match entries with ~PROPERTY~ set on the entry; if t, also match entries with inheritance. If ~INHERIT~ is not specified, use the Boolean value of ~org-use-property-inheritance~, which see (i.e. it is only interpreted as nil or non-nil). If ~MULTI~ is non-nil, also check for multi-value properties.
|
||||||
+ =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.
|
+ =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.
|
||||||
- Aliases: =r=.
|
- Aliases: =r=.
|
||||||
+ =rifle (&rest strings)= :: Return non-nil if each string is found in either the entry or its outline path. Works like =org-rifle=. This is probably the most useful, intuitive, general-purpose predicate.
|
+ =rifle (&rest strings)= :: Return non-nil if each string is found in either the entry or its outline path. Works like =org-rifle=. This is probably the most useful, intuitive, general-purpose predicate.
|
||||||
|
|
|
||||||
31
org-ql.el
31
org-ql.el
|
|
@ -1784,13 +1784,14 @@ priority B)."
|
||||||
(cl-loop for priority-arg in args
|
(cl-loop for priority-arg in args
|
||||||
thereis (= item-priority (* 1000 (- org-lowest-priority (string-to-char priority-arg)))))))))
|
thereis (= item-priority (* 1000 (- org-lowest-priority (string-to-char priority-arg)))))))))
|
||||||
|
|
||||||
(org-ql-defpred property (property &optional value &key inherit)
|
(org-ql-defpred property (property &optional value &key inherit multi)
|
||||||
"Return non-nil if current entry has PROPERTY, and optionally VALUE.
|
"Return non-nil if current entry has PROPERTY, and optionally VALUE.
|
||||||
If INHERIT is nil, only match entries with PROPERTY set on the
|
If INHERIT is nil, only match entries with PROPERTY set on the
|
||||||
entry; if t, also match entries with inheritance. If INHERIT is
|
entry; if t, also match entries with inheritance. If INHERIT is
|
||||||
not specified, use the Boolean value of
|
not specified, use the Boolean value of
|
||||||
`org-use-property-inheritance', which see (i.e. it is only
|
`org-use-property-inheritance', which see (i.e. it is only
|
||||||
interpreted as nil or non-nil)."
|
interpreted as nil or non-nil). If MULTI is non-nil, also check for
|
||||||
|
multi-value properties."
|
||||||
:normalizers ((`(,predicate-names)
|
:normalizers ((`(,predicate-names)
|
||||||
;; HACK: This clause protects against the case in
|
;; HACK: This clause protects against the case in
|
||||||
;; which the arguments are nil, which would cause an
|
;; which the arguments are nil, which would cause an
|
||||||
|
|
@ -1811,26 +1812,31 @@ interpreted as nil or non-nil)."
|
||||||
(list 'property property value
|
(list 'property property value
|
||||||
:inherit (if (plist-member plist :inherit)
|
:inherit (if (plist-member plist :inherit)
|
||||||
(plist-get plist :inherit)
|
(plist-get plist :inherit)
|
||||||
org-use-property-inheritance))))
|
org-use-property-inheritance)
|
||||||
|
:multi (when (plist-member plist :multi)
|
||||||
|
(plist-get plist :multi)))))
|
||||||
;; MAYBE: Should case folding be disabled for properties? What about values?
|
;; MAYBE: Should case folding be disabled for properties? What about values?
|
||||||
;; MAYBE: Support (property) without args.
|
;; MAYBE: Support (property) without args.
|
||||||
|
|
||||||
;; NOTE: When inheritance is enabled, the preamble can't be used,
|
;; NOTE: When inheritance is enabled, the preamble can't be used,
|
||||||
;; which will make the search slower.
|
;; which will make the search slower.
|
||||||
:preambles ((`(,predicate-names ,property ,value . ,(map :inherit))
|
:preambles ((`(,predicate-names ,property ,value ,(map :multi) . ,(map :inherit))
|
||||||
;; We do NOT return nil, because the predicate still needs to be tested,
|
;; We do NOT return nil, because the predicate still needs to be tested,
|
||||||
;; because the regexp could match a string not inside a property drawer.
|
;; because the regexp could match a string not inside a property drawer.
|
||||||
(list :regexp (unless inherit
|
(list :regexp (unless inherit
|
||||||
(rx-to-string `(seq bol (0+ space) ":" ,property ":"
|
(rx-to-string `(seq bol (0+ space) ":" ,property
|
||||||
|
,@(when multi '((? "+"))) ":"
|
||||||
(1+ space) ,value (0+ space) eol)))
|
(1+ space) ,value (0+ space) eol)))
|
||||||
:query query))
|
:query query))
|
||||||
(`(,predicate-names ,property . ,(map :inherit))
|
(`(,predicate-names ,property ,(map :multi) . ,(map :inherit))
|
||||||
;; We do NOT return nil, because the predicate still needs to be tested,
|
;; We do NOT return nil, because the predicate still needs to be tested,
|
||||||
;; because the regexp could match a string not inside a property drawer.
|
;; because the regexp could match a string not inside a property drawer.
|
||||||
;; NOTE: The preamble only matches if there appears to be a value.
|
;; NOTE: The preamble only matches if there appears to be a value.
|
||||||
;; A line like ":ID: " without any other text does not match.
|
;; A line like ":ID: " without any other text does not match.
|
||||||
(list :regexp (unless inherit
|
(list :regexp (unless inherit
|
||||||
(rx-to-string `(seq bol (0+ space) ":" ,property ":" (1+ space)
|
(rx-to-string `(seq bol (0+ space) ":" ,property
|
||||||
|
,@(when multi '((? "+")))
|
||||||
|
":" (1+ space)
|
||||||
(minimal-match (1+ not-newline)) eol)))
|
(minimal-match (1+ not-newline)) eol)))
|
||||||
:query query)))
|
:query query)))
|
||||||
:body
|
:body
|
||||||
|
|
@ -1848,9 +1854,18 @@ interpreted as nil or non-nil)."
|
||||||
;; TODO: Since --value-at doesn't account for inheritance,
|
;; TODO: Since --value-at doesn't account for inheritance,
|
||||||
;; we should generalize --tags-at to also work for property
|
;; we should generalize --tags-at to also work for property
|
||||||
;; inheritance and use it here, which should be much faster.
|
;; inheritance and use it here, which should be much faster.
|
||||||
|
(if multi
|
||||||
|
(when-let (values (org-ql--value-at
|
||||||
|
(point) (lambda ()
|
||||||
|
;; The default separator is space
|
||||||
|
(let ((org-property-separators `((,property . "\n"))))
|
||||||
|
(org-entry-get (point) property inherit)))))
|
||||||
|
(seq-some (lambda (v)
|
||||||
|
(string-equal value v))
|
||||||
|
(split-string values "\n")))
|
||||||
(string-equal value (org-ql--value-at
|
(string-equal value (org-ql--value-at
|
||||||
(point) (lambda ()
|
(point) (lambda ()
|
||||||
(org-entry-get (point) property inherit)))))))))
|
(org-entry-get (point) property inherit))))))))))
|
||||||
|
|
||||||
;; TODO: Add property-local, property-inherit, etc. to match tags predicates.
|
;; TODO: Add property-local, property-inherit, etc. to match tags predicates.
|
||||||
;; TODO: Add tests for property inheritance.
|
;; TODO: Add tests for property inheritance.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue