Compare commits

..

26 commits

Author SHA1 Message Date
Jiri Jakes
ed23480e4b Apply #459
Some checks failed
CI / build (27.1) (push) Has been cancelled
CI / build (27.2) (push) Has been cancelled
CI / build (28.1) (push) Has been cancelled
CI / build (28.2) (push) Has been cancelled
CI / build (29.1) (push) Has been cancelled
CI / build (29.2) (push) Has been cancelled
CI / build (29.3) (push) Has been cancelled
CI / build (29.4) (push) Has been cancelled
CI / build (snapshot) (push) Has been cancelled
2026-08-17 19:55:50 +08:00
Adam Porter
4b8330a683
Merge pull request #491 from alhassy/master
Docs: Remove grammatical typo from “org-ql-search-block”
2025-04-20 20:33:00 -05:00
Musa Al-hassy
9946299bec Docs: Remove grammatical typo from “org-ql-search-block” 2025-04-20 07:50:43 -04:00
Adam Porter
98c62ab0a6 Docs: Fix some predicate arguments
Reported-by: Trevoke <https://github.com/Trevoke>
2024-11-25 17:49:54 -06:00
Adam Porter
a5650e2be8 Merge: v0.8.10 2024-11-06 21:45:09 -06:00
Adam Porter
9c53c1bddf Release: v0.8.10 2024-11-06 21:43:13 -06:00
Adam Porter
c95bb8a3ef Fix: (org-ql-refile) Use base buffer
See #466.
2024-11-06 21:42:40 -06:00
Adam Porter
0e68cc9fac Fix: (link) Don't match against null groups
e.g. in a source block containing Bash shell code like:

  [[ -z $data ]]

The matched groups could be null, since it's not actually an Org link,
so calling STRING-MATCH-P on them would signal an error.

Reported-by: John Wiegley <jwiegley@gmail.com>
2024-11-06 21:42:27 -06:00
Adam Porter
3cfc77d2ff Meta: v0.8.10-pre 2024-11-06 21:42:10 -06:00
Adam Porter
b6f8a315e9 Fix: (org-ql-view--format-element) Font-lock Org syntax
Not sure why I overlooked this for so long (links already worked,
which is probably why).
2024-09-16 18:25:02 -05:00
Adam Porter
fff110acde Fix: (org-ql-refile) Use base buffer
Should probably release this in a v0.8.10.

See #466.
2024-09-16 13:42:17 -05:00
Adam Porter
d574b60551 Add: (defface org-ql-view-query) 2024-09-11 01:50:16 -05:00
Adam Porter
82f762e31c Add: (org-ql-view-relative-deadline-prefix) 2024-09-11 01:01:30 -05:00
Adam Porter
a3c0205a68 Fix: (defface org-ql-view-due-date) Customization group 2024-09-10 22:38:19 -05:00
Adam Porter
1c8c89f264 Add: (defface org-ql-view-title) Use in -view--header-line-format
Note that we also add a safety check in ORG-QL-VIEW--LINK-FOLLOW,
because the addition of a call to PROPERTIZE in
ORG-QL-VIEW--HEADER-LINE-FORMAT effectively removes what was
functioning as a safety check there (as CONCAT had been signaling an
error for the unsafe argument, whereas PROPERTIZE, which is called to
apply the new face, does not).  We also change the expected error in
the tests accordingly.
2024-09-10 22:37:19 -05:00
Adam Porter
c3519fb4a0 Merge: v0.8.9 2024-09-05 18:58:13 -05:00
Adam Porter
81281350d4 Release: v0.8.9 2024-09-05 18:56:47 -05:00
Adam Porter
e241354fd6 Fix: (org-ql--define-query-preamble-fn) Pcase pattern for Emacs 30
Now all tests and lints pass on Emacs versions 27.1-29.4, and the
current 30.0.50-ish snapshot build.

Note: This change was originally applied on master, but it seems
reasonable to apply it to this stable bugfix release now.

Fixes #433.

Reported-by: Akira Komamura <akira.komamura@gmail.com>
Co-developed-by: Stefan Monnier <monnier@iro.umontreal.ca>
2024-09-05 18:45:58 -05:00
Adam Porter
5ea97d2272 Fix: (level) Check number argument for preamble
This allows a query like this:

  (level <= (string-to-number (property PROPERTY)))

to proceed without signaling an error from ORG-QL--QUERY-PREAMBLE.

See #460.

Reported-by: Stewmath <https://github.com/Stewmath>
2024-09-05 18:35:19 -05:00
Adam Porter
3e7f48ad7e Meta: (test.yml) Also test on Emacs 29.1-29.4 2024-09-05 04:26:59 -05:00
Adam Porter
c77bade432 Tests: Fix filenames for CI (better)
This is much simpler.
2024-09-05 04:25:59 -05:00
Adam Porter
86d338729f Fix: (property) Calling like (property PROPERTY :inherit t)
Supporting this form isn't really required, since it violates the
CL-style argument parsing of CL-DEFUN, but it's convenient, and
probably saves some hair-pulling for users who are less familiar with
Elisp.

Fixes #460.

Reported-by: Stewmath <https://github.com/Stewmath>
2024-09-05 04:24:24 -05:00
Adam Porter
a373e812d0 Fix: (org-ql-view--link-follow) Reading link parameters
This is needed due to changes in Emacs 30, but this code was always
mistaken, and it just happened to work.

See <https://github.com/jorgenschaefer/emacs-buttercup/issues/247>.

Fixes #441.

Suggested-by: Ola Nilsson <ola.nilsson@gmail.com>
2024-09-04 23:48:34 -05:00
Adam Porter
bcb77b75cc Meta: v0.8.9-pre 2024-09-04 21:55:10 -05:00
Adam Porter
831a1d4736 Tests: Fix filenames for CI (better)
This is much simpler.
2024-09-04 21:47:53 -05:00
Adam Porter
f72feb8018 Revert "Tests: Fix filename tests for CI"
This reverts commit 611198155d.
2024-09-04 21:40:36 -05:00
7 changed files with 365 additions and 209 deletions

View file

@ -233,7 +233,7 @@ Note that the =effort=, =level=, and =priority= predicates do not support compar
Arguments are listed next to predicate names, where applicable. Arguments are listed next to predicate names, where applicable.
+ =blocked= :: Return non-nil if current heading is blocked. Calls ~org-entry-blocked-p~, which see. + =blocked= :: Return non-nil if current heading is blocked. Calls ~org-entry-blocked-p~, which see.
+ =category (&optional categories)= :: Return non-nil if current heading is in one or more of ~CATEGORIES~ (a list of strings). + =category (&rest categories)= :: Return non-nil if current heading is in one or more of ~CATEGORIES~ (a list of strings).
+ =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~.
+ =effort (&optional effort-or-comparator effort)= :: Return non-nil if current heading's effort property matches arguments. The following forms are accepted: ~(effort DURATION)~: Matches if effort is ~DURATION~. ~(effort DURATION DURATION)~: Matches if effort is between DURATIONs, inclusive. ~(effort COMPARATOR DURATION)~: Matches if effort compares to ~DURATION~ with ~COMPARATOR~. ~COMPARATOR~ may be ~<~, ~<=~, ~>~, or ~>=~. ~DURATION~ should be an Org effort string, like =5= or =0:05=. + =effort (&optional effort-or-comparator effort)= :: Return non-nil if current heading's effort property matches arguments. The following forms are accepted: ~(effort DURATION)~: Matches if effort is ~DURATION~. ~(effort DURATION DURATION)~: Matches if effort is between DURATIONs, inclusive. ~(effort COMPARATOR DURATION)~: Matches if effort compares to ~DURATION~ with ~COMPARATOR~. ~COMPARATOR~ may be ~<~, ~<=~, ~>~, or ~>=~. ~DURATION~ should be an Org effort string, like =5= or =0:05=.
+ =habit= :: Return non-nil if entry is a habit. + =habit= :: Return non-nil if entry is a habit.
@ -256,16 +256,16 @@ Arguments are listed next to predicate names, where applicable.
- Aliases: ~smart~. - Aliases: ~smart~.
- *Note:* By default, this is the default predicate used for plain-string query tokens (i.e. given without a specified predicate). This can be customized with the option ~org-ql-default-predicate~. - *Note:* By default, this is the default predicate used for plain-string query tokens (i.e. given without a specified predicate). This can be customized with the option ~org-ql-default-predicate~.
+ ~src (&key lang regexps)~ :: Return non-nil if current entry contains an Org Babel source block. If ~LANG~ is non-nil, match blocks of that language. If ~REGEXPS~ is non-nil, require that block's contents match all regexps. Matching is done case-insensitively. + ~src (&key lang regexps)~ :: Return non-nil if current entry contains an Org Babel source block. If ~LANG~ is non-nil, match blocks of that language. If ~REGEXPS~ is non-nil, require that block's contents match all regexps. Matching is done case-insensitively.
+ =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 (&rest 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. + =tags-inherited (&rest 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~. - Aliases: ~inherited-tags~, ~tags-i~, ~itags~.
+ =tags-local (&optional tags)= :: Return non-nil if current heading's local tags include one or more of ~TAGS~ (a list of strings). If ~TAGS~ is nil, return non-nil if heading has any local tags. + =tags-local (&rest tags)= :: Return non-nil if current heading's local tags include one or more of ~TAGS~ (a list of strings). If ~TAGS~ is nil, return non-nil if heading has any local tags.
- Aliases: ~local-tags~, ~tags-l~, ~ltags~. - Aliases: ~local-tags~, ~tags-l~, ~ltags~.
+ =tags-all (tags)= :: Return non-nil if current heading includes all of ~TAGS~. Tests both inherited and local tags. + =tags-all (&rest tags)= :: Return non-nil if current heading includes all of ~TAGS~. Tests both inherited and local tags.
- Aliases: ~tags&~. - Aliases: ~tags&~.
+ =tags-regexp (&rest regexps)= :: Return non-nil if current heading has tags matching one or more of ~REGEXPS~. Tests both inherited and local tags. + =tags-regexp (&rest regexps)= :: Return non-nil if current heading has tags matching one or more of ~REGEXPS~. Tests both inherited and local tags.
- 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 (&rest 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 *** Ancestor/descendant predicates
@ -556,17 +556,39 @@ Simple links may also be written manually in either sexp or non-sexp form, like:
** 0.9-pre ** 0.9-pre
*Additions*
+ Face ~org-ql-view-query~, applied to view queries in header line.
+ Face ~org-ql-view-title~, applied to view titles in header line.
+ Option ~org-ql-view-relative-deadline-prefix~.
*Changes* *Changes*
+ Command ~org-ql-find~ respects narrowing of the current buffer by default, allowing searching within the narrowed region. (Using one ~C-u~ argument widens the current buffer, and using two ~C-u~ arguments prompts for the buffers to search.) + Command ~org-ql-find~ respects narrowing of the current buffer by default, allowing searching within the narrowed region. (Using one ~C-u~ argument widens the current buffer, and using two ~C-u~ arguments prompts for the buffers to search.)
+ Function ~org-ql-completing-read~ accepts a new ~NARROWP~ argument, which is passed to ~org-ql-select~. + Function ~org-ql-completing-read~ accepts a new ~NARROWP~ argument, which is passed to ~org-ql-select~.
*Compatibility* *Fixes*
+ Fix compilation error on Emacs 30. ([[https://github.com/alphapapa/org-ql/issues/433][#433]]. Thanks to [[https://github.com/akirak][Akira Komamura]] and [[https://github.com/monnier][Stefan Monnier]].) + Customization group for face ~org-ql-view-due-date~.
+ Apply Org syntax font-locking to items in ~org-ql-view~ buffers.
*** helm-org-ql *** helm-org-ql
Tagged v0.6.2, fixing a compilation warning. Tagged v0.6.2, fixing a compilation warning.
** 0.8.10
*Fixes*
+ Command ~org-ql-refile~ uses the base buffer when refiling to an indirect buffer. ([[https://github.com/alphapapa/org-ql/issues/466][#466]].)
+ Predicate ~link~ could signal an error when searching text that is mistakenly recognized as an Org link (e.g. Bash double-bracket constructs in a source block). (Thanks to [[https://github.com/jwiegley][John Wiegley]] for reporting.)
** 0.8.9
*Fixes*
+ Predicate ~property~ when called with argument form ~(property "PROPERTY-NAME" :inherit t)~. ([[https://github.com/alphapapa/org-ql/issues/460][#460]]. Thanks to [[https://github.com/Stewmath][Stewmath]] for reporting.)
+ Predicate ~level~'s preamble optimizer allows expressions in place of the numeric argument. (See [[https://github.com/alphapapa/org-ql/issues/460][#460]]. Thanks to [[https://github.com/Stewmath][Stewmath]] for reporting.)
+ Reading of view settings from Org links in upcoming Emacs version. ([[https://github.com/alphapapa/org-ql/issues/461][#461]]. Thanks to [[https://github.com/snogge][Ola Nilsson]] for help debugging, and for maintaining [[https://github.com/jorgenschaefer/emacs-buttercup][Buttercup]].)
*Compatibility*
+ Fix compilation error on Emacs 30. ([[https://github.com/alphapapa/org-ql/issues/433][#433]]. Thanks to [[https://github.com/akirak][Akira Komamura]] and [[https://github.com/monnier][Stefan Monnier]].)
** 0.8.8 ** 0.8.8
*Fixes* *Fixes*

View file

@ -122,18 +122,20 @@ which see (but only the files are used)."
((and (pred listp) files) files))) ((and (pred listp) files) files)))
(list files-spec))))))) (list files-spec)))))))
(list (org-ql-completing-read buffers-files :prompt "Refile to: ")))) (list (org-ql-completing-read buffers-files :prompt "Refile to: "))))
(org-refile nil nil (let ((buffer (or (buffer-base-buffer (marker-buffer marker))
;; The RFLOC argument: (marker-buffer marker))))
(list (org-refile nil nil
;; Name ;; The RFLOC argument:
(org-with-point-at marker (list
(nth 4 (org-heading-components))) ;; Name
;; File (org-with-point-at marker
(buffer-file-name (marker-buffer marker)) (nth 4 (org-heading-components)))
;; nil ;; File
nil (buffer-file-name buffer)
;; Position ;; nil
marker))) nil
;; Position
marker))))
;;;###autoload ;;;###autoload
(defun org-ql-find-in-agenda () (defun org-ql-find-in-agenda ()

View file

@ -240,7 +240,7 @@ Like other agenda block commands, it searches files returned by
function `org-agenda-files'. Inserts a newline after the block. function `org-agenda-files'. Inserts a newline after the block.
If `org-ql-block-header' is non-nil, it is used as the header If `org-ql-block-header' is non-nil, it is used as the header
string for the block, otherwise a the header is formed string for the block, otherwise the header is formed
automatically from the query." automatically from the query."
(pcase-let ((`(,query . ,(map :header :sort)) args) (pcase-let ((`(,query . ,(map :header :sort)) args)
(narrow-p) (old-beg) (old-end)) (narrow-p) (old-beg) (old-end))

View file

@ -57,7 +57,18 @@
(defface org-ql-view-due-date (defface org-ql-view-due-date
'((t (:slant italic :weight bold))) '((t (:slant italic :weight bold)))
"Face for due dates in `org-ql-view' views." "Face for due dates in `org-ql-view' views."
:group 'org-ql) :group 'org-ql-view)
(defface org-ql-view-query nil
"View query in header line.
This face is added to the formatted query after font-lock faces
are applied to it. It may be used, e.g. to reduce the height so
more of it is visible."
:group 'org-ql-view)
(defface org-ql-view-title '((t :weight bold))
"View title in header line."
:group 'org-ql-view)
;;;; Variables ;;;; Variables
@ -238,6 +249,12 @@ See info node `(elisp)Cyclic Window Ordering'."
(sexp :tag "org-super-agenda grouping expression") (sexp :tag "org-super-agenda grouping expression")
(variable :tag "Variable holding org-super-agenda grouping expression")))))))) (variable :tag "Variable holding org-super-agenda grouping expression"))))))))
(defcustom org-ql-view-relative-deadline-prefix "due "
;; TODO(v0.9): Add one for scheduled, too.
"Prefix for relative deadlines.
Relative deadlines are, e.g. \"in 5d\", \"5d ago\"."
:type 'string)
;;;; Commands ;;;; Commands
;;;###autoload ;;;###autoload
@ -459,7 +476,8 @@ subsequent refreshing of the buffer: `org-ql-view-buffers-files',
If TITLE, prepend it to the header." If TITLE, prepend it to the header."
(let* ((title (if title (let* ((title (if title
(concat (propertize "View:" 'face 'transient-argument) (concat (propertize "View:" 'face 'transient-argument)
title " ") (propertize title 'face 'org-ql-view-title)
" ")
"")) ""))
(query-formatted (when query (query-formatted (when query
(org-ql-view--format-query query))) (org-ql-view--format-query query)))
@ -478,6 +496,7 @@ If TITLE, prepend it to the header."
(org-ql-view--font-lock-string 'emacs-lisp-mode) (org-ql-view--font-lock-string 'emacs-lisp-mode)
(s-truncate available-width)) (s-truncate available-width))
'help-echo buffers-files-formatted)))) 'help-echo buffers-files-formatted))))
(add-face-text-property 0 (length query-propertized) 'org-ql-view-query 'append query-propertized)
(concat title (concat title
(when query (propertize "Query:" 'face 'transient-argument)) (when query (propertize "Query:" 'face 'transient-argument))
(when query query-propertized) (when query query-propertized)
@ -509,6 +528,22 @@ with human-readable strings."
(font-lock-ensure) (font-lock-ensure)
(buffer-string)))) (buffer-string))))
(defun org-ql-view--font-lock-as-org (s)
"Return string S font-locked as in `org-mode'."
;; This works like `org-fontify-like-in-org-mode', but uses a single
;; buffer instead of a new one every time.
;; TODO(C): Submit these improvements upstream.
(let ((buffer (or (get-buffer " *org-ql-view--font-lock-as-org*")
(with-current-buffer (get-buffer-create " *org-ql-view--font-lock-as-org*")
(buffer-disable-undo)
(org-mode)
(current-buffer)))))
(with-current-buffer buffer
(insert s)
(font-lock-ensure)
(prog1 (buffer-string)
(erase-buffer)))))
(defun org-ql-view--buffer (&optional name) (defun org-ql-view--buffer (&optional name)
"Return `org-ql-view' buffer, creating it if necessary. "Return `org-ql-view' buffer, creating it if necessary.
If NAME is non-nil, return buffer by that name instead of using If NAME is non-nil, return buffer by that name instead of using
@ -626,7 +661,7 @@ purposes of compatibility with changes in Org 9.4."
(query (url-unhex-string query)) (query (url-unhex-string query))
(params (when params (url-parse-query-string params))) (params (when params (url-parse-query-string params)))
;; `url-parse-query-string' returns "improper" alists, which makes this awkward. ;; `url-parse-query-string' returns "improper" alists, which makes this awkward.
(sort (when-let* ((stored-string (alist-get "sort" params nil nil #'string=)) (sort (when-let* ((stored-string (car (alist-get "sort" params nil nil #'string=)))
(read-value (read stored-string))) (read-value (read stored-string)))
;; Ensure the value is either a symbol or list of symbols (which excludes lambdas). ;; Ensure the value is either a symbol or list of symbols (which excludes lambdas).
(unless (or (symbolp read-value) (cl-every #'symbolp read-value)) (unless (or (symbolp read-value) (cl-every #'symbolp read-value))
@ -634,17 +669,19 @@ purposes of compatibility with changes in Org 9.4."
read-value)) read-value))
read-value)) read-value))
(org-super-agenda-allow-unsafe-groups nil) ; Disallow unsafe group selectors. (org-super-agenda-allow-unsafe-groups nil) ; Disallow unsafe group selectors.
(groups (--when-let (alist-get "super-groups" params nil nil #'string=) (groups (--when-let (car (alist-get "super-groups" params nil nil #'string=))
(read it))) (read it)))
(title (--when-let (alist-get "title" params nil nil #'string=) (title (--when-let (car (alist-get "title" params nil nil #'string=))
(read it))) (read it)))
(buffers-files (--if-let (alist-get "buffers-files" params nil nil #'string=) (buffers-files (--if-let (car (alist-get "buffers-files" params nil nil #'string=))
(org-ql-view--expand-buffers-files (read it)) (org-ql-view--expand-buffers-files (read it))
(current-buffer)))) (current-buffer))))
(unless (or (bufferp buffers-files) (unless (or (bufferp buffers-files)
(stringp buffers-files) (stringp buffers-files)
(cl-every #'stringp buffers-files)) (cl-every #'stringp buffers-files))
(error "CAUTION: Link not opened because unsafe buffers-files parameter detected: %s" buffers-files)) (error "CAUTION: Link not opened because unsafe buffers-files parameter detected: %s" buffers-files))
(unless (or (stringp title) (null title))
(error "CAUTION: Link not opened because unsafe title parameter detected: %S" title))
(when (or (listp query) (when (or (listp query)
(string-match (rx bol (0+ space) "(") query)) (string-match (rx bol (0+ space) "(") query))
;; SAFETY: Query is in sexp form: ask for confirmation, because it could contain arbitrary code. ;; SAFETY: Query is in sexp form: ask for confirmation, because it could contain arbitrary code.
@ -877,6 +914,11 @@ return an empty string."
;; (which would also make it easier to do it independently of faces, etc). ;; (which would also make it easier to do it independently of faces, etc).
(title (--> (org-ql-view--add-faces element) (title (--> (org-ql-view--add-faces element)
(org-element-property :raw-value it))) (org-element-property :raw-value it)))
;; TODO(B): Needs refactoring. A function like `org-ql-view--add-faces'
;; should return a list of faces to be added.
(title-faces (get-text-property 0 'face title))
(title (org-ql-view--font-lock-as-org title))
(_ (add-face-text-property 0 (length title) title-faces t title))
(todo-keyword (-some--> (org-element-property :todo-keyword element) (todo-keyword (-some--> (org-element-property :todo-keyword element)
(org-ql-view--add-todo-face (org-ql-view--add-todo-face
(substring-no-properties it)))) (substring-no-properties it))))
@ -1014,7 +1056,9 @@ property."
(deadline-day-number (org-time-string-to-absolute (deadline-day-number (org-time-string-to-absolute
(org-element-timestamp-interpreter deadline-date 'ignore))) (org-element-timestamp-interpreter deadline-date 'ignore)))
(difference-days (- today-day-number deadline-day-number)) (difference-days (- today-day-number deadline-day-number))
(relative-due-date (org-add-props (org-ql-view--format-relative-date difference-days) nil (relative-due-date (org-add-props
(concat org-ql-view-relative-deadline-prefix
(org-ql-view--format-relative-date difference-days)) nil
'help-echo (org-element-property :raw-value deadline-date))) 'help-echo (org-element-property :raw-value deadline-date)))
;; FIXME: Unused for now: (todo-keyword (org-element-property :todo-keyword element)) ;; FIXME: Unused for now: (todo-keyword (org-element-property :todo-keyword element))
;; FIXME: Unused for now: (done-p (member todo-keyword org-done-keywords)) ;; FIXME: Unused for now: (done-p (member todo-keyword org-done-keywords))

View file

@ -1537,7 +1537,8 @@ COMPARATOR may be `<', `<=', `>', or `>='."
;; is "h:" while the user is typing. ;; is "h:" while the user is typing.
(list :regexp (rx bol (1+ "*") " ") (list :regexp (rx bol (1+ "*") " ")
:case-fold t)) :case-fold t))
(`(,predicate-names ,comparator-or-num ,num) ((and `(,predicate-names ,comparator-or-num ,num)
(guard (numberp num)))
(let ((repeat (pcase comparator-or-num (let ((repeat (pcase comparator-or-num
('< `(repeat 1 ,(1- num) "*")) ('< `(repeat 1 ,(1- num) "*"))
('<= `(repeat 1 ,num "*")) ('<= `(repeat 1 ,num "*"))
@ -1546,7 +1547,8 @@ COMPARATOR may be `<', `<=', `>', or `>='."
((pred integerp) `(repeat ,comparator-or-num ,num "*"))))) ((pred integerp) `(repeat ,comparator-or-num ,num "*")))))
(list :regexp (rx-to-string `(seq bol ,repeat " ") t) (list :regexp (rx-to-string `(seq bol ,repeat " ") t)
:case-fold t))) :case-fold t)))
(`(,predicate-names ,num) ((and `(,predicate-names ,num)
(guard (numberp num)))
(list :regexp (rx-to-string `(seq bol (repeat ,num "*") " ") t) (list :regexp (rx-to-string `(seq bol (repeat ,num "*") " ") t)
:case-fold t))) :case-fold t)))
;; NOTE: It might be necessary to take into account `org-odd-levels'; see docstring for ;; NOTE: It might be necessary to take into account `org-odd-levels'; see docstring for
@ -1624,11 +1626,15 @@ any link is found."
(or (null description) (or (null description)
(string-match-p description (match-string org-ql-link-description-group))))) (string-match-p description (match-string org-ql-link-description-group)))))
(_ (if (and description target) (_ (if (and description target)
(and (string-match-p target (match-string 1)) (and (and (match-string 1)
(string-match-p description (match-string org-ql-link-description-group))) (string-match-p target (match-string 1)))
(or (string-match-p description-or-target (match-string 1)) (and (match-string org-ql-link-description-group)
(string-match-p description-or-target (string-match-p description (match-string org-ql-link-description-group))))
(match-string org-ql-link-description-group))))))))) (or (and (match-string 1)
(string-match-p description-or-target (match-string 1)))
(and (match-string org-ql-link-description-group)
(string-match-p description-or-target
(match-string org-ql-link-description-group))))))))))
(org-ql-defpred (rifle smart) (&rest strings) (org-ql-defpred (rifle smart) (&rest strings)
"Return non-nil if each of strings is found in the entry or its outline path. "Return non-nil if each of strings is found in the entry or its outline path.
@ -1802,34 +1808,62 @@ interpreted as nil or non-nil)."
;; predicate test for whether an entry has local ;; predicate test for whether an entry has local
;; properties when no arguments are given. ;; properties when no arguments are given.
(list 'property "")) (list 'property ""))
(`(,predicate-names ,property ,value . ,plist) (`(,predicate-names ,property)
;; Convert keyword property arguments to strings. Non-sexp ;; Convert keyword property arguments to strings. Non-sexp
;; queries result in keyword property arguments (because to do ;; queries result in keyword property arguments (because to do
;; otherwise would require ugly special-casing in the parsing). ;; otherwise would require ugly special-casing in the parsing).
(when (keywordp property) (when (keywordp property)
(setf property (substring (symbol-name property) 1))) (setf property (substring (symbol-name property) 1)))
(list 'property property value (list 'property property))
:inherit (cond ((plist-member plist :inherit) (plist-get plist :inherit)) (`(,predicate-names ,property . ,rest)
((listp org-use-property-inheritance) ''selective) (pcase rest
(t org-use-property-inheritance))))) (`(,value)
;; Convert keyword property arguments to strings. Non-sexp
;; queries result in keyword property arguments (because to do
;; otherwise would require ugly special-casing in the parsing).
(when (keywordp property)
(setf property (substring (symbol-name property) 1)))
(list 'property property value))
((and `(,value . ,plist)
(guard (not (keywordp value))))
;; Convert keyword property arguments to strings. Non-sexp
;; queries result in keyword property arguments (because to do
;; otherwise would require ugly special-casing in the parsing).
(when (keywordp property)
(setf property (substring (symbol-name property) 1)))
(list 'property property value
:inherit (cond ((plist-member plist :inherit) (plist-get plist :inherit))
((listp org-use-property-inheritance) ''selective)
(t org-use-property-inheritance))))
((and plist (guard (keywordp (car rest))))
;; Convert keyword property arguments to strings. Non-sexp
;; queries result in keyword property arguments (because to do
;; otherwise would require ugly special-casing in the parsing).
(when (keywordp property)
(setf property (substring (symbol-name property) 1)))
(list 'property property nil
:inherit (cond ((plist-member plist :inherit) (plist-get plist :inherit))
((listp org-use-property-inheritance) ''selective)
(t org-use-property-inheritance)))))))
;; 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 (((and `(,predicate-names ,property ,value)
(guard (atom value)))
;; 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 (rx-to-string `(seq bol (0+ space) ":" ,property ":"
(rx-to-string `(seq bol (0+ space) ":" ,property ":" (1+ space) ,value (0+ space) eol))
(1+ space) ,value (0+ space) eol)))
:query query)) :query query))
(`(,predicate-names ,property . ,(map :inherit)) ((and `(,predicate-names ,property ,value . ,plist)
;; We do NOT return nil, because the predicate still needs to be tested, (guard (keywordp (car plist))))
;; 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 (plist-get plist :inherit)
(rx-to-string `(seq bol (0+ space) ":" ,property ":" (1+ space) (rx-to-string `(seq bol (0+ space) ":" ,property ":" (1+ space)
(minimal-match (1+ not-newline)) eol))) (minimal-match (1+ not-newline)) eol)))
:query query))) :query query)))
@ -1841,7 +1875,7 @@ interpreted as nil or non-nil)."
;; Check that PROPERTY exists ;; Check that PROPERTY exists
(org-ql--value-at (org-ql--value-at
(point) (lambda () (point) (lambda ()
(org-entry-get (point) property)))) (org-entry-get (point) property inherit))))
(_ (_
;; Check that PROPERTY has VALUE. ;; Check that PROPERTY has VALUE.

View file

@ -74,6 +74,8 @@ Functions / Macros
Changelog Changelog
* 0.9-pre: 09-pre. * 0.9-pre: 09-pre.
* 0.8.10: 0810.
* 0.8.9: 089.
* 0.8.8: 088. * 0.8.8: 088.
* 0.8.7: 087. * 0.8.7: 087.
* 0.8.6: 086. * 0.8.6: 086.
@ -1047,6 +1049,8 @@ releases.
* Menu: * Menu:
* 0.9-pre: 09-pre. * 0.9-pre: 09-pre.
* 0.8.10: 0810.
* 0.8.9: 089.
* 0.8.8: 088. * 0.8.8: 088.
* 0.8.7: 087. * 0.8.7: 087.
* 0.8.6: 086. * 0.8.6: 086.
@ -1088,12 +1092,17 @@ releases.
* 0.1: 01. * 0.1: 01.
 
File: README.info, Node: 09-pre, Next: 088, Up: Changelog File: README.info, Node: 09-pre, Next: 0810, Up: Changelog
5.1 0.9-pre 5.1 0.9-pre
=========== ===========
*Changes* *Additions*
• Face org-ql-view-query, applied to view queries in header line.
• Face org-ql-view-title, applied to view titles in header line.
• Option org-ql-view-relative-deadline-prefix.
*Changes*
• Command org-ql-find respects narrowing of the current buffer by • Command org-ql-find respects narrowing of the current buffer by
default, allowing searching within the narrowed region. (Using one default, allowing searching within the narrowed region. (Using one
C-u argument widens the current buffer, and using two C-u C-u argument widens the current buffer, and using two C-u
@ -1101,11 +1110,9 @@ File: README.info, Node: 09-pre, Next: 088, Up: Changelog
• Function org-ql-completing-read accepts a new NARROWP argument, • Function org-ql-completing-read accepts a new NARROWP argument,
which is passed to org-ql-select. which is passed to org-ql-select.
*Compatibility* *Fixes*
• Fix compilation error on Emacs 30. (#433 • Customization group for face org-ql-view-due-date.
(https://github.com/alphapapa/org-ql/issues/433). Thanks to Akira • Apply Org syntax font-locking to items in org-ql-view buffers.
Komamura (https://github.com/akirak) and Stefan Monnier
(https://github.com/monnier).)
* Menu: * Menu:
@ -1120,9 +1127,51 @@ File: README.info, Node: helm-org-ql (1), Up: 09-pre
Tagged v0.6.2, fixing a compilation warning. Tagged v0.6.2, fixing a compilation warning.
 
File: README.info, Node: 088, Next: 087, Prev: 09-pre, Up: Changelog File: README.info, Node: 0810, Next: 089, Prev: 09-pre, Up: Changelog
5.2 0.8.8 5.2 0.8.10
==========
*Fixes*
• Command org-ql-refile uses the base buffer when refiling to an
indirect buffer. (#466
(https://github.com/alphapapa/org-ql/issues/466).)
• Predicate link could signal an error when searching text that is
mistakenly recognized as an Org link (e.g. Bash double-bracket
constructs in a source block). (Thanks to John Wiegley
(https://github.com/jwiegley) for reporting.)

File: README.info, Node: 089, Next: 088, Prev: 0810, Up: Changelog
5.3 0.8.9
=========
*Fixes*
• Predicate property when called with argument form (property
"PROPERTY-NAME" :inherit t). (#460
(https://github.com/alphapapa/org-ql/issues/460). Thanks to
Stewmath (https://github.com/Stewmath) for reporting.)
• Predicate levels preamble optimizer allows expressions in place
of the numeric argument. (See #460
(https://github.com/alphapapa/org-ql/issues/460). Thanks to
Stewmath (https://github.com/Stewmath) for reporting.)
• Reading of view settings from Org links in upcoming Emacs version.
(#461 (https://github.com/alphapapa/org-ql/issues/461). Thanks to
Ola Nilsson (https://github.com/snogge) for help debugging, and for
maintaining Buttercup
(https://github.com/jorgenschaefer/emacs-buttercup).)
*Compatibility*
• Fix compilation error on Emacs 30. (#433
(https://github.com/alphapapa/org-ql/issues/433). Thanks to Akira
Komamura (https://github.com/akirak) and Stefan Monnier
(https://github.com/monnier).)

File: README.info, Node: 088, Next: 087, Prev: 089, Up: Changelog
5.4 0.8.8
========= =========
*Fixes* *Fixes*
@ -1144,7 +1193,7 @@ File: README.info, Node: 088, Next: 087, Prev: 09-pre, Up: Changelog
 
File: README.info, Node: 087, Next: 086, Prev: 088, Up: Changelog File: README.info, Node: 087, Next: 086, Prev: 088, Up: Changelog
5.3 0.8.7 5.5 0.8.7
========= =========
*Fixes* *Fixes*
@ -1172,7 +1221,7 @@ File: README.info, Node: 087, Next: 086, Prev: 088, Up: Changelog
 
File: README.info, Node: 086, Next: 085, Prev: 087, Up: Changelog File: README.info, Node: 086, Next: 085, Prev: 087, Up: Changelog
5.4 0.8.6 5.6 0.8.6
========= =========
*Fixes* *Fixes*
@ -1182,7 +1231,7 @@ File: README.info, Node: 086, Next: 085, Prev: 087, Up: Changelog
 
File: README.info, Node: 085, Next: 084, Prev: 086, Up: Changelog File: README.info, Node: 085, Next: 084, Prev: 086, Up: Changelog
5.5 0.8.5 5.7 0.8.5
========= =========
*Fixes* *Fixes*
@ -1199,7 +1248,7 @@ File: README.info, Node: 085, Next: 084, Prev: 086, Up: Changelog
 
File: README.info, Node: 084, Next: 083, Prev: 085, Up: Changelog File: README.info, Node: 084, Next: 083, Prev: 085, Up: Changelog
5.6 0.8.4 5.8 0.8.4
========= =========
*Fixes* *Fixes*
@ -1213,7 +1262,7 @@ File: README.info, Node: 084, Next: 083, Prev: 085, Up: Changelog
 
File: README.info, Node: 083, Next: 082, Prev: 084, Up: Changelog File: README.info, Node: 083, Next: 082, Prev: 084, Up: Changelog
5.7 0.8.3 5.9 0.8.3
========= =========
*Fixes* *Fixes*
@ -1226,8 +1275,8 @@ File: README.info, Node: 083, Next: 082, Prev: 084, Up: Changelog
 
File: README.info, Node: 082, Next: 081, Prev: 083, Up: Changelog File: README.info, Node: 082, Next: 081, Prev: 083, Up: Changelog
5.8 0.8.2 5.10 0.8.2
========= ==========
*Fixes* *Fixes*
@ -1240,8 +1289,8 @@ File: README.info, Node: 082, Next: 081, Prev: 083, Up: Changelog
 
File: README.info, Node: 081, Next: 08, Prev: 082, Up: Changelog File: README.info, Node: 081, Next: 08, Prev: 082, Up: Changelog
5.9 0.8.1 5.11 0.8.1
========= ==========
*Fixes* *Fixes*
@ -1255,7 +1304,7 @@ File: README.info, Node: 081, Next: 08, Prev: 082, Up: Changelog
 
File: README.info, Node: 08, Next: 074, Prev: 081, Up: Changelog File: README.info, Node: 08, Next: 074, Prev: 081, Up: Changelog
5.10 0.8 5.12 0.8
======== ========
*Additions* *Additions*
@ -1311,7 +1360,7 @@ File: README.info, Node: 08, Next: 074, Prev: 081, Up: Changelog
 
File: README.info, Node: 074, Next: 073, Prev: 08, Up: Changelog File: README.info, Node: 074, Next: 073, Prev: 08, Up: Changelog
5.11 0.7.4 5.13 0.7.4
========== ==========
*Fixes* *Fixes*
@ -1321,7 +1370,7 @@ File: README.info, Node: 074, Next: 073, Prev: 08, Up: Changelog
 
File: README.info, Node: 073, Next: 072, Prev: 074, Up: Changelog File: README.info, Node: 073, Next: 072, Prev: 074, Up: Changelog
5.12 0.7.3 5.14 0.7.3
========== ==========
*Fixes* *Fixes*
@ -1339,7 +1388,7 @@ File: README.info, Node: 073, Next: 072, Prev: 074, Up: Changelog
 
File: README.info, Node: 072, Next: 071, Prev: 073, Up: Changelog File: README.info, Node: 072, Next: 071, Prev: 073, Up: Changelog
5.13 0.7.2 5.15 0.7.2
========== ==========
*Fixes* *Fixes*
@ -1360,7 +1409,7 @@ File: README.info, Node: 072, Next: 071, Prev: 073, Up: Changelog
 
File: README.info, Node: 071, Next: 07, Prev: 072, Up: Changelog File: README.info, Node: 071, Next: 07, Prev: 072, Up: Changelog
5.14 0.7.1 5.16 0.7.1
========== ==========
*Fixes* *Fixes*
@ -1379,7 +1428,7 @@ File: README.info, Node: 071, Next: 07, Prev: 072, Up: Changelog
 
File: README.info, Node: 07, Next: 063, Prev: 071, Up: Changelog File: README.info, Node: 07, Next: 063, Prev: 071, Up: Changelog
5.15 0.7 5.17 0.7
======== ========
*Added* *Added*
@ -1438,7 +1487,7 @@ File: README.info, Node: 07, Next: 063, Prev: 071, Up: Changelog
 
File: README.info, Node: 063, Next: 062, Prev: 07, Up: Changelog File: README.info, Node: 063, Next: 062, Prev: 07, Up: Changelog
5.16 0.6.3 5.18 0.6.3
========== ==========
*Fixed* *Fixed*
@ -1454,7 +1503,7 @@ File: README.info, Node: 063, Next: 062, Prev: 07, Up: Changelog
 
File: README.info, Node: 062, Next: 061, Prev: 063, Up: Changelog File: README.info, Node: 062, Next: 061, Prev: 063, Up: Changelog
5.17 0.6.2 5.19 0.6.2
========== ==========
*Fixed* *Fixed*
@ -1465,7 +1514,7 @@ File: README.info, Node: 062, Next: 061, Prev: 063, Up: Changelog
 
File: README.info, Node: 061, Next: 06, Prev: 062, Up: Changelog File: README.info, Node: 061, Next: 06, Prev: 062, Up: Changelog
5.18 0.6.1 5.20 0.6.1
========== ==========
*Fixed* *Fixed*
@ -1483,7 +1532,7 @@ File: README.info, Node: 061, Next: 06, Prev: 062, Up: Changelog
 
File: README.info, Node: 06, Next: 052, Prev: 061, Up: Changelog File: README.info, Node: 06, Next: 052, Prev: 061, Up: Changelog
5.19 0.6 5.21 0.6
======== ========
*Added* *Added*
@ -1550,7 +1599,7 @@ File: README.info, Node: 06, Next: 052, Prev: 061, Up: Changelog
 
File: README.info, Node: 052, Next: 051, Prev: 06, Up: Changelog File: README.info, Node: 052, Next: 051, Prev: 06, Up: Changelog
5.20 0.5.2 5.22 0.5.2
========== ==========
*Fixed* *Fixed*
@ -1561,7 +1610,7 @@ File: README.info, Node: 052, Next: 051, Prev: 06, Up: Changelog
 
File: README.info, Node: 051, Next: 05, Prev: 052, Up: Changelog File: README.info, Node: 051, Next: 05, Prev: 052, Up: Changelog
5.21 0.5.1 5.23 0.5.1
========== ==========
*Fixed* *Fixed*
@ -1574,7 +1623,7 @@ File: README.info, Node: 051, Next: 05, Prev: 052, Up: Changelog
 
File: README.info, Node: 05, Next: 049, Prev: 051, Up: Changelog File: README.info, Node: 05, Next: 049, Prev: 051, Up: Changelog
5.22 0.5 5.24 0.5
======== ========
*Added* *Added*
@ -1615,7 +1664,7 @@ File: README.info, Node: 05, Next: 049, Prev: 051, Up: Changelog
 
File: README.info, Node: 049, Next: 048, Prev: 05, Up: Changelog File: README.info, Node: 049, Next: 048, Prev: 05, Up: Changelog
5.23 0.4.9 5.25 0.4.9
========== ==========
*Fixed* *Fixed*
@ -1626,7 +1675,7 @@ File: README.info, Node: 049, Next: 048, Prev: 05, Up: Changelog
 
File: README.info, Node: 048, Next: 047, Prev: 049, Up: Changelog File: README.info, Node: 048, Next: 047, Prev: 049, Up: Changelog
5.24 0.4.8 5.26 0.4.8
========== ==========
*Fixed* *Fixed*
@ -1638,7 +1687,7 @@ File: README.info, Node: 048, Next: 047, Prev: 049, Up: Changelog
 
File: README.info, Node: 047, Next: 046, Prev: 048, Up: Changelog File: README.info, Node: 047, Next: 046, Prev: 048, Up: Changelog
5.25 0.4.7 5.27 0.4.7
========== ==========
*Fixed* *Fixed*
@ -1651,7 +1700,7 @@ File: README.info, Node: 047, Next: 046, Prev: 048, Up: Changelog
 
File: README.info, Node: 046, Next: 045, Prev: 047, Up: Changelog File: README.info, Node: 046, Next: 045, Prev: 047, Up: Changelog
5.26 0.4.6 5.28 0.4.6
========== ==========
*Fixed* *Fixed*
@ -1664,7 +1713,7 @@ File: README.info, Node: 046, Next: 045, Prev: 047, Up: Changelog
 
File: README.info, Node: 045, Next: 044, Prev: 046, Up: Changelog File: README.info, Node: 045, Next: 044, Prev: 046, Up: Changelog
5.27 0.4.5 5.29 0.4.5
========== ==========
*Fixed* *Fixed*
@ -1676,7 +1725,7 @@ File: README.info, Node: 045, Next: 044, Prev: 046, Up: Changelog
 
File: README.info, Node: 044, Next: 043, Prev: 045, Up: Changelog File: README.info, Node: 044, Next: 043, Prev: 045, Up: Changelog
5.28 0.4.4 5.30 0.4.4
========== ==========
*Fixed* *Fixed*
@ -1688,7 +1737,7 @@ File: README.info, Node: 044, Next: 043, Prev: 045, Up: Changelog
 
File: README.info, Node: 043, Next: 042, Prev: 044, Up: Changelog File: README.info, Node: 043, Next: 042, Prev: 044, Up: Changelog
5.29 0.4.3 5.31 0.4.3
========== ==========
*Fixed* *Fixed*
@ -1698,7 +1747,7 @@ File: README.info, Node: 043, Next: 042, Prev: 044, Up: Changelog
 
File: README.info, Node: 042, Next: 041, Prev: 043, Up: Changelog File: README.info, Node: 042, Next: 041, Prev: 043, Up: Changelog
5.30 0.4.2 5.32 0.4.2
========== ==========
*Fixed* *Fixed*
@ -1707,7 +1756,7 @@ File: README.info, Node: 042, Next: 041, Prev: 043, Up: Changelog
 
File: README.info, Node: 041, Next: 04, Prev: 042, Up: Changelog File: README.info, Node: 041, Next: 04, Prev: 042, Up: Changelog
5.31 0.4.1 5.33 0.4.1
========== ==========
*Fixed* *Fixed*
@ -1717,7 +1766,7 @@ File: README.info, Node: 041, Next: 04, Prev: 042, Up: Changelog
 
File: README.info, Node: 04, Next: 032, Prev: 041, Up: Changelog File: README.info, Node: 04, Next: 032, Prev: 041, Up: Changelog
5.32 0.4 5.34 0.4
======== ========
_Note:_ The next release, 0.5, may include changes which will require _Note:_ The next release, 0.5, may include changes which will require
@ -1798,7 +1847,7 @@ automatically, as they will be pushed to the master branch when ready.
 
File: README.info, Node: 032, Next: 031, Prev: 04, Up: Changelog File: README.info, Node: 032, Next: 031, Prev: 04, Up: Changelog
5.33 0.3.2 5.35 0.3.2
========== ==========
*Fixed* *Fixed*
@ -1811,7 +1860,7 @@ File: README.info, Node: 032, Next: 031, Prev: 04, Up: Changelog
 
File: README.info, Node: 031, Next: 03, Prev: 032, Up: Changelog File: README.info, Node: 031, Next: 03, Prev: 032, Up: Changelog
5.34 0.3.1 5.36 0.3.1
========== ==========
*Fixed* *Fixed*
@ -1821,7 +1870,7 @@ File: README.info, Node: 031, Next: 03, Prev: 032, Up: Changelog
 
File: README.info, Node: 03, Next: 023, Prev: 031, Up: Changelog File: README.info, Node: 03, Next: 023, Prev: 031, Up: Changelog
5.35 0.3 5.37 0.3
======== ========
*Added* *Added*
@ -1889,7 +1938,7 @@ File: README.info, Node: 03, Next: 023, Prev: 031, Up: Changelog
 
File: README.info, Node: 023, Next: 022, Prev: 03, Up: Changelog File: README.info, Node: 023, Next: 022, Prev: 03, Up: Changelog
5.36 0.2.3 5.38 0.2.3
========== ==========
*Fixed* *Fixed*
@ -1899,7 +1948,7 @@ File: README.info, Node: 023, Next: 022, Prev: 03, Up: Changelog
 
File: README.info, Node: 022, Next: 021, Prev: 023, Up: Changelog File: README.info, Node: 022, Next: 021, Prev: 023, Up: Changelog
5.37 0.2.2 5.39 0.2.2
========== ==========
*Fixed* *Fixed*
@ -1910,7 +1959,7 @@ File: README.info, Node: 022, Next: 021, Prev: 023, Up: Changelog
 
File: README.info, Node: 021, Next: 02, Prev: 022, Up: Changelog File: README.info, Node: 021, Next: 02, Prev: 022, Up: Changelog
5.38 0.2.1 5.40 0.2.1
========== ==========
*Fixed* *Fixed*
@ -1920,7 +1969,7 @@ File: README.info, Node: 021, Next: 02, Prev: 022, Up: Changelog
 
File: README.info, Node: 02, Next: 01, Prev: 021, Up: Changelog File: README.info, Node: 02, Next: 01, Prev: 021, Up: Changelog
5.39 0.2 5.41 0.2
======== ========
*Added* *Added*
@ -2003,7 +2052,7 @@ File: README.info, Node: 02, Next: 01, Prev: 021, Up: Changelog
 
File: README.info, Node: 01, Prev: 02, Up: Changelog File: README.info, Node: 01, Prev: 02, Up: Changelog
5.40 0.1 5.42 0.1
======== ========
First tagged release. First tagged release.
@ -2088,88 +2137,90 @@ GPLv3
 
Tag Table: Tag Table:
Node: Top225 Node: Top225
Node: Contents2079 Node: Contents2109
Node: Screenshots2206 Node: Screenshots2236
Node: Installation2324 Node: Installation2354
Node: Quelpa2838 Node: Quelpa2868
Node: Helm support3366 Node: Helm support3396
Node: Usage3769 Node: Usage3799
Node: Commands4167 Node: Commands4197
Node: org-ql-find4632 Node: org-ql-find4662
Node: org-ql-open-link5540 Node: org-ql-open-link5570
Node: org-ql-refile6395 Node: org-ql-refile6425
Node: org-ql-search6723 Node: org-ql-search6753
Node: helm-org-ql8654 Node: helm-org-ql8684
Node: org-ql-view9032 Node: org-ql-view9062
Node: org-ql-view-sidebar9562 Node: org-ql-view-sidebar9592
Node: org-ql-view-recent-items9942 Node: org-ql-view-recent-items9972
Node: org-ql-sparse-tree10438 Node: org-ql-sparse-tree10468
Node: Queries11238 Node: Queries11268
Node: Non-sexp query syntax12355 Node: Non-sexp query syntax12385
Node: General predicates14114 Node: General predicates14144
Node: Ancestor/descendant predicates21039 Node: Ancestor/descendant predicates21069
Node: Date/time predicates22167 Node: Date/time predicates22197
Node: Functions / Macros25291 Node: Functions / Macros25321
Node: Agenda-like views25589 Node: Agenda-like views25619
Ref: Function org-ql-block25751 Ref: Function org-ql-block25781
Node: Listing / acting-on results27012 Node: Listing / acting-on results27042
Ref: Caching27220 Ref: Caching27250
Ref: Function org-ql-select28133 Ref: Function org-ql-select28163
Ref: Function org-ql-query30559 Ref: Function org-ql-query30589
Ref: Macro org-ql (deprecated)32333 Ref: Macro org-ql (deprecated)32363
Node: Custom predicates32648 Node: Custom predicates32678
Ref: Macro org-ql-defpred32872 Ref: Macro org-ql-defpred32902
Node: Dynamic block36313 Node: Dynamic block36343
Node: Links39037 Node: Links39067
Node: Tips39724 Node: Tips39754
Node: Changelog40048 Node: Changelog40078
Node: 09-pre41001 Node: 09-pre41061
Node: helm-org-ql (1)41785 Node: helm-org-ql (1)41987
Node: 08841926 Node: 081042128
Node: 08743005 Node: 08942657
Node: 08644233 Node: 08843797
Node: 08544467 Node: 08744873
Node: 08445123 Node: 08646101
Node: 08345575 Node: 08546335
Node: 08245916 Node: 08446991
Node: 08146309 Node: 08347443
Node: 0846730 Node: 08247784
Node: 07449456 Node: 08148179
Node: 07349681 Node: 0848602
Node: 07250415 Node: 07451328
Node: 07151336 Node: 07351553
Node: 0752147 Node: 07252287
Node: 06355013 Node: 07153208
Node: 06255546 Node: 0754019
Node: 06155853 Node: 06356885
Node: 0656423 Node: 06257418
Node: 05259479 Node: 06157725
Node: 05159781 Node: 0658295
Node: 0560206 Node: 05261351
Node: 04961737 Node: 05161653
Node: 04862019 Node: 0562078
Node: 04762368 Node: 04963609
Node: 04662777 Node: 04863891
Node: 04563185 Node: 04764240
Node: 04463546 Node: 04664649
Node: 04363905 Node: 04565057
Node: 04264108 Node: 04465418
Node: 04164269 Node: 04365777
Node: 0464516 Node: 04265980
Node: 03268617 Node: 04166141
Node: 03169020 Node: 0466388
Node: 0369217 Node: 03270489
Node: 02372517 Node: 03170892
Node: 02272751 Node: 0371089
Node: 02173031 Node: 02374389
Node: 0273236 Node: 02274623
Node: 0177314 Node: 02174903
Node: Development77415 Node: 0275108
Node: Copyright assignment77648 Node: 0179186
Node: Notes78238 Node: Development79287
Node: Comparison with Org Agenda searches78402 Node: Copyright assignment79520
Node: org-sidebar79291 Node: Notes80110
Node: License79570 Node: Comparison with Org Agenda searches80274
Node: org-sidebar81163
Node: License81442
 
End Tag Table End Tag Table

View file

@ -638,6 +638,11 @@ with keyword arg NOW in PLIST."
:to-equal (list :query t :to-equal (list :query t
:preamble (rx bol (repeat 2 4 "*") " ") :preamble (rx bol (repeat 2 4 "*") " ")
:preamble-case-fold t))) :preamble-case-fold t)))
(it "with an expression in level number's place"
(expect (org-ql--query-preamble '(level <= (string-to-number (property "PROPERTY"))))
:to-equal (list :query '(level <= (string-to-number (property "PROPERTY")))
:preamble nil
:preamble-case-fold t)))
(it "<" (it "<"
(expect (org-ql--query-preamble '(level < 3)) (expect (org-ql--query-preamble '(level < 3))
:to-equal (list :query t :to-equal (list :query t
@ -1339,7 +1344,15 @@ with keyword arg NOW in PLIST."
(org-ql-it "with a property and a value" (org-ql-it "with a property and a value"
(org-ql-expect ('(property "agenda-group" "plans")) (org-ql-expect ('(property "agenda-group" "plans"))
'("Take over the universe" "Write a symphony")))) '("Take over the universe" "Write a symphony")))
(org-ql-it "with a property and \"nil :inherit t\""
(org-ql-expect ('(property "agenda-group" nil :inherit t))
'("Take over the 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" "Spaceship lease" "Recurring" "/r/emacs" "Shop for groceries" "Sunrise/sunset" "Write a symphony")))
(org-ql-it "with a property and \":inherit t\""
(org-ql-expect ('(property "agenda-group" :inherit t))
'("Take over the 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" "Spaceship lease" "Recurring" "/r/emacs" "Shop for groceries" "Sunrise/sunset" "Write a symphony"))))
(describe "(regexp)" (describe "(regexp)"
@ -1973,13 +1986,13 @@ with keyword arg NOW in PLIST."
(expression-link "[[org-ql-search:todo:?title%3D%28error%20%22UNSAFE%22%29]]")) (expression-link "[[org-ql-search:todo:?title%3D%28error%20%22UNSAFE%22%29]]"))
(it "Errors for a quoted lambda" (it "Errors for a quoted lambda"
(expect (open-link quoted-lambda-link) (expect (open-link quoted-lambda-link)
:to-throw 'wrong-type-argument '(characterp lambda))) :to-throw 'error '("CAUTION: Link not opened because unsafe title parameter detected: (lambda (_ _) (error \"UNSAFE\"))")))
(it "Errors for an unquoted lambda" (it "Errors for an unquoted lambda"
(expect (open-link unquoted-lambda-link) (expect (open-link unquoted-lambda-link)
:to-throw 'wrong-type-argument '(characterp lambda))) :to-throw 'error '("CAUTION: Link not opened because unsafe title parameter detected: (lambda (_ _) (error \"UNSAFE\"))")))
(it "Errors for an expression" (it "Errors for an expression"
(expect (open-link expression-link) (expect (open-link expression-link)
:to-throw 'wrong-type-argument '(characterp error)))) :to-throw 'error '("CAUTION: Link not opened because unsafe title parameter detected: (error \"UNSAFE\")"))))
(describe "sort parameter" (describe "sort parameter"
:var ((quoted-lambda-link "[[org-ql-search:todo:?sort%3D%28lambda%20%28_%20_%29%20%28error%20%22UNSAFE%22%29%29]]") :var ((quoted-lambda-link "[[org-ql-search:todo:?sort%3D%28lambda%20%28_%20_%29%20%28error%20%22UNSAFE%22%29%29]]")
@ -2005,7 +2018,7 @@ with keyword arg NOW in PLIST."
(describe "View saving/loading" (describe "View saving/loading"
:var* ((temp-dir (make-temp-file "test-org-ql-" 'dir)) :var* ((temp-dir (make-temp-file "test-org-ql-" 'dir))
(temp-filenames (cl-loop for file in '("test1.org" "test2.org") (temp-filenames (cl-loop for file in '("test1.org" "test2.org")
collect (expand-file-name file temp-dir))) collect (abbreviate-file-name (expand-file-name file temp-dir))))
(file-contents (with-temp-buffer (file-contents (with-temp-buffer
(insert "#+TITLE: Test data\n\n" (insert "#+TITLE: Test data\n\n"
"* TODO Heading 1\n" "* TODO Heading 1\n"
@ -2111,31 +2124,21 @@ with keyword arg NOW in PLIST."
(describe "Buffers/Files" (describe "Buffers/Files"
:var ((query '(and (todo "TODO") (regexp "heading"))) :var ((query '(and (todo "TODO") (regexp "heading")))
(one-filename (car temp-filenames))) (one-filename (car temp-filenames)))
;; NOTE: Inexplicably, on GitHub CI, the filenames are being (it "One filename matches"
;; abbreviated (i.e. "/home/FOO" is replaced with "~/FOO"); (expect (var-after-bookmark-set-and-jump 'org-ql-view-buffers-files one-filename query)
;; I can only guess it's something to do with the way the :to-equal one-filename))
;; Emacs instance is built in the Nix images we use there. (it "A list of filenames matches"
;; So we have to compare the filenames in abbreviated form. (expect (var-after-bookmark-set-and-jump 'org-ql-view-buffers-files temp-filenames query)
(cl-labels ((filenames-equal-p (a b) :to-equal temp-filenames))
(seq-set-equal-p (mapcar #'abbreviate-file-name a) ;; NOTE: These actually bookmark the filenames backing the buffers.
(mapcar #'abbreviate-file-name b)))) (it "One buffer matches"
(it "One filename matches" (expect (var-after-bookmark-set-and-jump 'org-ql-view-buffers-files
(should (equal (abbreviate-file-name (find-file-noselect (car temp-filenames)) query)
(var-after-bookmark-set-and-jump 'org-ql-view-buffers-files one-filename query)) :to-equal one-filename))
(abbreviate-file-name one-filename)))) (it "A list of buffers matches"
(it "A list of filenames matches" (expect (var-after-bookmark-set-and-jump 'org-ql-view-buffers-files
(should (filenames-equal-p (var-after-bookmark-set-and-jump 'org-ql-view-buffers-files temp-filenames query) (mapcar #'find-file-noselect temp-filenames) query)
temp-filenames))) :to-equal temp-filenames)))))
;; NOTE: These actually bookmark the filenames backing the buffers.
(it "One buffer matches"
(should (equal (abbreviate-file-name
(var-after-bookmark-set-and-jump 'org-ql-view-buffers-files
(find-file-noselect (car temp-filenames)) query))
(abbreviate-file-name one-filename))))
(it "A list of buffers matches"
(should (filenames-equal-p (var-after-bookmark-set-and-jump 'org-ql-view-buffers-files
(mapcar #'find-file-noselect temp-filenames) query)
temp-filenames)))))))
(describe "Dynamic blocks" (describe "Dynamic blocks"
(describe "warn about sexp queries" (describe "warn about sexp queries"