Fix: Planning-related predicates searched too far into entries
Planning-line-related predicates searched entire entries, which could find lines that looked like planning lines but were not. For example, in an entry talking about tiny.el, in a source code block, in Elisp comments that had text resembling an Org planning line, that text would be found by the regexp search, and the predicate would then attempt to parse the match, which could fail. Now the regexp search for planning-line-related predicates is bound by the end of the line after the heading, which is the only place that actual Org planning lines are supposed to be.
This commit is contained in:
parent
d8d2455a2c
commit
e839397579
2 changed files with 25 additions and 13 deletions
|
|
@ -476,6 +476,7 @@ Expands into a call to ~org-ql-select~ with the same arguments. For convenience
|
||||||
+ Don't search buffers without headings, and show a message if the user attempts it.
|
+ Don't search buffers without headings, and show a message if the user attempts it.
|
||||||
+ Don't search hidden/special buffers.
|
+ Don't search hidden/special buffers.
|
||||||
+ Properly accept arbitrary sort functions in =org-ql-select=, etc. (Fixes [[https://github.com/alphapapa/org-ql/issues/37][#37]]. Thanks to [[https://github.com/mz-pdm][Milan Zamazal]].)
|
+ Properly accept arbitrary sort functions in =org-ql-select=, etc. (Fixes [[https://github.com/alphapapa/org-ql/issues/37][#37]]. Thanks to [[https://github.com/mz-pdm][Milan Zamazal]].)
|
||||||
|
+ Planning-line-related predicates searched too far into entries.
|
||||||
|
|
||||||
*Compatibility*
|
*Compatibility*
|
||||||
+ Fixes for compatibility with Org 9.2. (Thanks to [[https://github.com/ataias][Ataias Pereira Reis]] and [[https://github.com/dakra][Daniel Kraus]].)
|
+ Fixes for compatibility with Org 9.2. (Thanks to [[https://github.com/ataias][Ataias Pereira Reis]] and [[https://github.com/dakra][Daniel Kraus]].)
|
||||||
|
|
|
||||||
33
org-ql.el
33
org-ql.el
|
|
@ -844,7 +844,8 @@ If ON, return non-nil if entry has a timestamp on date ON.
|
||||||
|
|
||||||
FROM, TO, and ON should be either `ts' structs, or strings
|
FROM, TO, and ON should be either `ts' structs, or strings
|
||||||
parseable by `parse-time-string' which may omit the time value."
|
parseable by `parse-time-string' which may omit the time value."
|
||||||
(org-ql--predicate-ts :from from :to to :regexp org-closed-time-regexp :match-group 1))
|
(org-ql--predicate-ts :from from :to to :regexp org-closed-time-regexp :match-group 1
|
||||||
|
:limit (line-end-position 2)))
|
||||||
|
|
||||||
(org-ql--defpred deadline (&key from to _on)
|
(org-ql--defpred deadline (&key from to _on)
|
||||||
;; The underscore before `on' prevents "unused lexical variable"
|
;; The underscore before `on' prevents "unused lexical variable"
|
||||||
|
|
@ -863,10 +864,13 @@ If ON, return non-nil if entry has a timestamp on date ON.
|
||||||
|
|
||||||
FROM, TO, and ON should be either `ts' structs, or strings
|
FROM, TO, and ON should be either `ts' structs, or strings
|
||||||
parseable by `parse-time-string' which may omit the time value."
|
parseable by `parse-time-string' which may omit the time value."
|
||||||
(org-ql--predicate-ts :from from :to to :regexp org-deadline-time-regexp :match-group 1))
|
(org-ql--predicate-ts :from from :to to :regexp org-deadline-time-regexp :match-group 1
|
||||||
|
:limit (line-end-position 2)))
|
||||||
|
|
||||||
(org-ql--defpred deadline-warning (&key from to)
|
(org-ql--defpred deadline-warning (&key from to)
|
||||||
"Internal selector used to handle `org-deadline-warning-days' and deadlines with warning periods."
|
"Internal selector used to handle `org-deadline-warning-days' and deadlines with warning periods.
|
||||||
|
Should be called on a planning line, because it does not search
|
||||||
|
past the end of the current line."
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(forward-line 1)
|
(forward-line 1)
|
||||||
(when (re-search-forward org-deadline-time-regexp (line-end-position) t)
|
(when (re-search-forward org-deadline-time-regexp (line-end-position) t)
|
||||||
|
|
@ -906,7 +910,8 @@ If ON, return non-nil if entry has a timestamp on date ON.
|
||||||
|
|
||||||
FROM, TO, and ON should be either `ts' structs, or strings
|
FROM, TO, and ON should be either `ts' structs, or strings
|
||||||
parseable by `parse-time-string' which may omit the time value."
|
parseable by `parse-time-string' which may omit the time value."
|
||||||
(org-ql--predicate-ts :from from :to to :regexp org-ql-planning-regexp :match-group 1))
|
(org-ql--predicate-ts :from from :to to :regexp org-ql-planning-regexp :match-group 1
|
||||||
|
:limit (line-end-position 2)))
|
||||||
|
|
||||||
(org-ql--defpred scheduled (&key from to _on)
|
(org-ql--defpred scheduled (&key from to _on)
|
||||||
;; The underscore before `on' prevents "unused lexical variable"
|
;; The underscore before `on' prevents "unused lexical variable"
|
||||||
|
|
@ -925,9 +930,10 @@ If ON, return non-nil if entry has a timestamp on date ON.
|
||||||
|
|
||||||
FROM, TO, and ON should be either `ts' structs, or strings
|
FROM, TO, and ON should be either `ts' structs, or strings
|
||||||
parseable by `parse-time-string' which may omit the time value."
|
parseable by `parse-time-string' which may omit the time value."
|
||||||
(org-ql--predicate-ts :from from :to to :regexp org-scheduled-time-regexp :match-group 1))
|
(org-ql--predicate-ts :from from :to to :regexp org-scheduled-time-regexp :match-group 1
|
||||||
|
:limit (line-end-position 2)))
|
||||||
|
|
||||||
(org-ql--defpred ts (&key from to _on regexp (match-group 0))
|
(org-ql--defpred ts (&key from to _on regexp (match-group 0) (limit (org-entry-end-position)))
|
||||||
;; The underscore before `on' prevents "unused lexical variable" warnings,
|
;; The underscore before `on' prevents "unused lexical variable" warnings,
|
||||||
;; because we pre-process that argument in a macro before this function is
|
;; because we pre-process that argument in a macro before this function is
|
||||||
;; called. The `regexp' argument is also provided by the macro and is not
|
;; called. The `regexp' argument is also provided by the macro and is not
|
||||||
|
|
@ -947,24 +953,29 @@ FROM, TO, and ON should be either `ts' structs, or strings
|
||||||
parseable by `parse-time-string' which may omit the time value.
|
parseable by `parse-time-string' which may omit the time value.
|
||||||
|
|
||||||
TYPE may be `active' to match active timestamps, `inactive' to
|
TYPE may be `active' to match active timestamps, `inactive' to
|
||||||
match inactive ones, or `both' / nil to match both types."
|
match inactive ones, or `both' / nil to match both types.
|
||||||
|
|
||||||
|
LIMIT bounds the search for the timestamp REGEXP. It defaults to
|
||||||
|
the end of the entry, i.e. the position returned by
|
||||||
|
`org-entry-end-position', but for certain searches it should be
|
||||||
|
bound to a different positiion, e.g. for planning lines, the end
|
||||||
|
of the line after the heading."
|
||||||
;; TODO: DRY this with the clocked predicate.
|
;; TODO: DRY this with the clocked predicate.
|
||||||
;; NOTE: FROM and TO are actually expected to be `ts' structs. The docstring is written
|
;; NOTE: FROM and TO are actually expected to be `ts' structs. The docstring is written
|
||||||
;; for end users, for which the arguments are pre-processed by `org-ql-select'.
|
;; for end users, for which the arguments are pre-processed by `org-ql-select'.
|
||||||
;; FIXME: This assumes every "clocked" entry is a range. Unclosed clock entries are not handled.
|
;; FIXME: This assumes every "clocked" entry is a range. Unclosed clock entries are not handled.
|
||||||
(cl-macrolet ((next-timestamp ()
|
(cl-macrolet ((next-timestamp ()
|
||||||
`(when (re-search-forward regexp end-pos t)
|
`(when (re-search-forward regexp limit t)
|
||||||
(ts-parse-org (match-string match-group))))
|
(ts-parse-org (match-string match-group))))
|
||||||
(test-timestamps (pred-form)
|
(test-timestamps (pred-form)
|
||||||
`(cl-loop for next-ts = (next-timestamp)
|
`(cl-loop for next-ts = (next-timestamp)
|
||||||
while next-ts
|
while next-ts
|
||||||
thereis ,pred-form)))
|
thereis ,pred-form)))
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(let ((end-pos (org-entry-end-position)))
|
(cond ((not (or from to)) (re-search-forward regexp limit t))
|
||||||
(cond ((not (or from to)) (re-search-forward regexp end-pos t))
|
|
||||||
((and from to) (test-timestamps (ts-in from to next-ts)))
|
((and from to) (test-timestamps (ts-in from to next-ts)))
|
||||||
(from (test-timestamps (ts<= from next-ts)))
|
(from (test-timestamps (ts<= from next-ts)))
|
||||||
(to (test-timestamps (ts<= next-ts to))))))))
|
(to (test-timestamps (ts<= next-ts to)))))))
|
||||||
|
|
||||||
;;;;; Sorting
|
;;;;; Sorting
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue