Compare commits

...
Sign in to create a new pull request.

4 commits

Author SHA1 Message Date
Adam Porter
870b0c9f52 WIP 2022-03-11 11:07:59 -06:00
Adam Porter
73871e04e0 WIP: (logbook) predicate 2022-03-07 13:56:36 -06:00
Adam Porter
af18eac2b8 Fix: Links to headings with stats cookies in dynamic blocks
Fixes #248.  Closes #249.

Thanks to Maikol Solis (@maikol-solis) for reporting, and to him and
Ihor Radchenko (@yantar92) for helping plan the fix.
2022-03-01 02:41:40 -06:00
Adam Porter
00d95e1f0f Meta: 0.7-pre 2022-03-01 02:25:48 -06:00
5 changed files with 200 additions and 80 deletions

View file

@ -522,6 +522,11 @@ Simple links may also be written manually in either sexp or non-sexp form, like:
/Note:/ Breaking changes may be made before version 1.0, but in the event of major changes, attempts at backward compatibility will be made with obsolescence declarations, translation of arguments, etc. Users who need stability guarantees before 1.0 may choose to use tagged stable releases.
** 0.7-pre
*Fixed*
+ In dynamic blocks, links to headings with statistics cookies were broken. (Fixes [[https://github.com/alphapapa/org-ql/issues/248][#248]]. Thanks to [[https://github.com/maikol-solis][Maikol Solis]] and [[https://github.com/yantar92][Ihor Radchenko]].)
** 0.6
*Added*

View file

@ -38,6 +38,15 @@
(require 'org-ql)
(require 'org-ql-view)
;;;; Compatibility
(defalias 'org-ql-search--link-heading-search-string
(cond ((fboundp 'org-link--normalize-string) #'org-link--normalize-string)
((fboundp 'org-link-heading-search-string) #'org-link-heading-search-string)
((fboundp 'org-make-org-heading-search-string) #'org-make-org-heading-search-string)
(t (warn "org-ql: Unable to define alias `org-ql-search--link-heading-search-string'. This may affect links in dynamic blocks. Please report this as a bug.")
#'identity)))
;;;; Variables
(defvar org-ql-block-header nil
@ -285,9 +294,9 @@ For example, an org-ql dynamic block header could look like:
(list (cons 'todo (lambda (element)
(org-element-property :todo-keyword element)))
(cons 'heading (lambda (element)
(org-make-link-string (org-element-property :raw-value element)
(org-link-display-format
(org-element-property :raw-value element)))))
(let ((normalized-heading
(org-ql-search--link-heading-search-string (org-element-property :raw-value element))))
(org-make-link-string normalized-heading (org-link-display-format normalized-heading)))))
(cons 'priority (lambda (element)
(--when-let (org-element-property :priority element)
(char-to-string it))))

View file

@ -2,7 +2,7 @@
;; Author: Adam Porter <adam@alphapapa.net>
;; Url: https://github.com/alphapapa/org-ql
;; Version: 0.6
;; Version: 0.7-pre
;; Package-Requires: ((emacs "26.1") (dash "2.18.1") (f "0.17.2") (map "2.1") (org "9.0") (org-super-agenda "1.2") (ov "1.0.6") (peg "1.0") (s "1.12.0") (transient "0.1") (ts "0.2-pre"))
;; Keywords: hypermedia, outlines, Org, agenda
@ -2134,6 +2134,89 @@ any planning prefix); it defaults to 0 (i.e. the whole regexp)."
(from (test-timestamps (ts<= from next-ts)))
(to (test-timestamps (ts<= next-ts to)))))))
;;;;;; Logbooks
(org-ql-defpred logbook (&key string from to on state regexp)
"Return non-nil if current entry has a logbook matching arguments.
FIXME: Document remaining arguments. NOTE: STRING argument is
accepted as first argument rather than only as keyword argument."
:normalizers
((`(,predicate-names . ,rest)
(let ((string (if (stringp (car rest))
(prog1
(regexp-quote (car rest))
(setf rest (cdr rest)))
(plist-get rest :string)))
(regexp (plist-get rest :regexp))
(state (plist-get rest :state)))
(org-ql--normalize-from-to-on
`(logbook :string ,string :regexp ,regexp :state ,state
:from ,from :to ,to :on ,on)))))
;; TODO: :preambles. When arguments are given, search for an
;; appropriate regexp, then use the :body predicate to confirm it's
;; in a logbook drawer. Without arguments, simply search for a
;; logbook drawer (though note that this would preclude using
;; entry-specific logbook drawer names).
:body
;; For now, we'll model part of this on `org-log-beginning', though
;; it may not be fast enough to run on every potential match.
;; NOTE: It's regrettable, but since any entry or subtree may define
;; its own logbook drawer name, to be correct, we must call
;; `org-log-into-drawer' for each entry. This also means concatting
;; a regexp string to match such a drawer.
;; TODO: Optionally assume default logbook drawer names and optimize
;; for that case.
(when-let ((drawer-name (org-log-into-drawer)))
;; Look for logbook drawer in entry.
(save-excursion
(org-end-of-meta-data)
(let ((drawer-regexp (concat "^[ \t]*:" (regexp-quote drawer-name) ":[ \t]*$"))
(end (if (org-at-heading-p)
(point)
(save-excursion
(outline-next-heading)
(point))))
(case-fold-search t))
(when-let ((drawer-element (cl-loop while (re-search-forward drawer-regexp end t)
for element = (org-element-at-point)
when (eq 'drawer (org-element-type element))
return element)))
;; Logbook drawer found: narrow to it and confirm that
;; arguments are found in it.
(save-restriction
(narrow-to-region (point) (org-element-property :contents-end drawer-element))
(and (or (not string)
(save-excursion
(re-search-forward string nil t)))
(or (not regexp)
(save-excursion
(re-search-forward regexp nil t)))
;; TODO: from, to, on, state
;; TODO: Search notes added like "- Note taken on
;; [2022-03-07 Mon 13:55] \\" (this starts to get
;; complicated; org-element might help, but might
;; also be too slow).
;; TODO: Without arguments, search for any logbook
;; entries.
)))))))
(defun org-ql--state-change-regexp (to &optional from)
"Return regexp matching logbook state-change line for states TO and FROM.
Regexp includes an inactive timestamp with hour:minute at
end-of-line."
(let ((from-regexp (if from
`(,(concat "\"" from "\"") (1+ blank))
'(""))))
(rx-to-string `(seq bol (0+ blank) "-" (repeat 1 2 " ") "State " "\"" ,to "\"" (1+ blank)
"from " ,@from-regexp (1+ blank)
(regexp ,org-ql-regexp-ts-inactive-with-time)))))
;; NOTE: Predicates defined: stop deferring and define normalizer and
;; preamble functions now. Reversing preserves the order in which
;; they were defined. Generally it shouldn't matter, but it might...

View file

@ -69,6 +69,7 @@ Functions / Macros
Changelog
* 0.7-pre: 07-pre.
* 0.6: 06.
* 0.5.2: 052.
* 0.5.1: 051.
@ -957,6 +958,7 @@ releases.
* Menu:
* 0.7-pre: 07-pre.
* 0.6: 06.
* 0.5.2: 052.
* 0.5.1: 051.
@ -981,9 +983,22 @@ releases.
* 0.1: 01.

File: README.info, Node: 06, Next: 052, Up: Changelog
File: README.info, Node: 07-pre, Next: 06, Up: Changelog
5.1 0.6
5.1 0.7-pre
===========
*Fixed*
• In dynamic blocks, links to headings with statistics cookies were
broken. (Fixes #248
(https://github.com/alphapapa/org-ql/issues/248). Thanks to Maikol
Solis (https://github.com/maikol-solis) and Ihor Radchenko
(https://github.com/yantar92).)

File: README.info, Node: 06, Next: 052, Prev: 07-pre, Up: Changelog
5.2 0.6
=======
*Added*
@ -1050,7 +1065,7 @@ File: README.info, Node: 06, Next: 052, Up: Changelog

File: README.info, Node: 052, Next: 051, Prev: 06, Up: Changelog
5.2 0.5.2
5.3 0.5.2
=========
*Fixed*
@ -1061,7 +1076,7 @@ File: README.info, Node: 052, Next: 051, Prev: 06, Up: Changelog

File: README.info, Node: 051, Next: 05, Prev: 052, Up: Changelog
5.3 0.5.1
5.4 0.5.1
=========
*Fixed*
@ -1074,7 +1089,7 @@ File: README.info, Node: 051, Next: 05, Prev: 052, Up: Changelog

File: README.info, Node: 05, Next: 049, Prev: 051, Up: Changelog
5.4 0.5
5.5 0.5
=======
*Added*
@ -1115,7 +1130,7 @@ File: README.info, Node: 05, Next: 049, Prev: 051, Up: Changelog

File: README.info, Node: 049, Next: 048, Prev: 05, Up: Changelog
5.5 0.4.9
5.6 0.4.9
=========
*Fixed*
@ -1126,7 +1141,7 @@ File: README.info, Node: 049, Next: 048, Prev: 05, Up: Changelog

File: README.info, Node: 048, Next: 047, Prev: 049, Up: Changelog
5.6 0.4.8
5.7 0.4.8
=========
*Fixed*
@ -1138,7 +1153,7 @@ File: README.info, Node: 048, Next: 047, Prev: 049, Up: Changelog

File: README.info, Node: 047, Next: 046, Prev: 048, Up: Changelog
5.7 0.4.7
5.8 0.4.7
=========
*Fixed*
@ -1151,7 +1166,7 @@ File: README.info, Node: 047, Next: 046, Prev: 048, Up: Changelog

File: README.info, Node: 046, Next: 045, Prev: 047, Up: Changelog
5.8 0.4.6
5.9 0.4.6
=========
*Fixed*
@ -1164,8 +1179,8 @@ File: README.info, Node: 046, Next: 045, Prev: 047, Up: Changelog

File: README.info, Node: 045, Next: 044, Prev: 046, Up: Changelog
5.9 0.4.5
=========
5.10 0.4.5
==========
*Fixed*
• Non-case-folding predicates like (todo) unnecessarily disabled
@ -1176,7 +1191,7 @@ File: README.info, Node: 045, Next: 044, Prev: 046, Up: Changelog

File: README.info, Node: 044, Next: 043, Prev: 045, Up: Changelog
5.10 0.4.4
5.11 0.4.4
==========
*Fixed*
@ -1188,7 +1203,7 @@ File: README.info, Node: 044, Next: 043, Prev: 045, Up: Changelog

File: README.info, Node: 043, Next: 042, Prev: 044, Up: Changelog
5.11 0.4.3
5.12 0.4.3
==========
*Fixed*
@ -1198,7 +1213,7 @@ File: README.info, Node: 043, Next: 042, Prev: 044, Up: Changelog

File: README.info, Node: 042, Next: 041, Prev: 043, Up: Changelog
5.12 0.4.2
5.13 0.4.2
==========
*Fixed*
@ -1207,7 +1222,7 @@ File: README.info, Node: 042, Next: 041, Prev: 043, Up: Changelog

File: README.info, Node: 041, Next: 04, Prev: 042, Up: Changelog
5.13 0.4.1
5.14 0.4.1
==========
*Fixed*
@ -1217,7 +1232,7 @@ File: README.info, Node: 041, Next: 04, Prev: 042, Up: Changelog

File: README.info, Node: 04, Next: 032, Prev: 041, Up: Changelog
5.14 0.4
5.15 0.4
========
_Note:_ The next release, 0.5, may include changes which will require
@ -1298,7 +1313,7 @@ as they will be pushed to the master branch when ready.

File: README.info, Node: 032, Next: 031, Prev: 04, Up: Changelog
5.15 0.3.2
5.16 0.3.2
==========
*Fixed*
@ -1311,7 +1326,7 @@ File: README.info, Node: 032, Next: 031, Prev: 04, Up: Changelog

File: README.info, Node: 031, Next: 03, Prev: 032, Up: Changelog
5.16 0.3.1
5.17 0.3.1
==========
*Fixed*
@ -1321,7 +1336,7 @@ File: README.info, Node: 031, Next: 03, Prev: 032, Up: Changelog

File: README.info, Node: 03, Next: 023, Prev: 031, Up: Changelog
5.17 0.3
5.18 0.3
========
*Added*
@ -1386,7 +1401,7 @@ File: README.info, Node: 03, Next: 023, Prev: 031, Up: Changelog

File: README.info, Node: 023, Next: 022, Prev: 03, Up: Changelog
5.18 0.2.3
5.19 0.2.3
==========
*Fixed*
@ -1396,7 +1411,7 @@ File: README.info, Node: 023, Next: 022, Prev: 03, Up: Changelog

File: README.info, Node: 022, Next: 021, Prev: 023, Up: Changelog
5.19 0.2.2
5.20 0.2.2
==========
*Fixed*
@ -1407,7 +1422,7 @@ File: README.info, Node: 022, Next: 021, Prev: 023, Up: Changelog

File: README.info, Node: 021, Next: 02, Prev: 022, Up: Changelog
5.20 0.2.1
5.21 0.2.1
==========
*Fixed*
@ -1417,7 +1432,7 @@ File: README.info, Node: 021, Next: 02, Prev: 022, Up: Changelog

File: README.info, Node: 02, Next: 01, Prev: 021, Up: Changelog
5.21 0.2
5.22 0.2
========
*Added*
@ -1500,7 +1515,7 @@ File: README.info, Node: 02, Next: 01, Prev: 021, Up: Changelog

File: README.info, Node: 01, Prev: 02, Up: Changelog
5.22 0.1
5.23 0.1
========
First tagged release.
@ -1558,58 +1573,59 @@ GPLv3

Tag Table:
Node: Top225
Node: Contents1689
Node: Screenshots1812
Node: Installation1930
Node: Quelpa2426
Node: Helm support2954
Node: Usage3345
Node: Commands3743
Node: org-ql-search4216
Node: helm-org-ql5866
Node: org-ql-view6226
Node: org-ql-view-sidebar6726
Node: org-ql-view-recent-items7082
Node: org-ql-sparse-tree7566
Node: Queries8366
Node: Non-sexp query syntax9477
Node: General predicates11201
Node: Ancestor/descendant predicates17422
Node: Date/time predicates18550
Node: Functions / Macros21638
Node: Agenda-like views21936
Node: Listing / acting-on results23341
Node: Custom predicates28977
Node: Dynamic block32636
Node: Links35348
Node: Tips36035
Node: Changelog36353
Node: 0637071
Node: 05240070
Node: 05140370
Node: 0540787
Node: 04942261
Node: 04842535
Node: 04742882
Node: 04643277
Node: 04543677
Node: 04444036
Node: 04344395
Node: 04244592
Node: 04144753
Node: 0444994
Node: 03248927
Node: 03149306
Node: 0349503
Node: 02352478
Node: 02252706
Node: 02152974
Node: 0253173
Node: 0157208
Node: Notes57309
Node: Comparison with Org Agenda searches57471
Node: org-sidebar58343
Node: License58622
Node: Contents1709
Node: Screenshots1832
Node: Installation1950
Node: Quelpa2446
Node: Helm support2974
Node: Usage3365
Node: Commands3763
Node: org-ql-search4236
Node: helm-org-ql5886
Node: org-ql-view6246
Node: org-ql-view-sidebar6746
Node: org-ql-view-recent-items7102
Node: org-ql-sparse-tree7586
Node: Queries8386
Node: Non-sexp query syntax9497
Node: General predicates11221
Node: Ancestor/descendant predicates17442
Node: Date/time predicates18570
Node: Functions / Macros21658
Node: Agenda-like views21956
Node: Listing / acting-on results23361
Node: Custom predicates28997
Node: Dynamic block32656
Node: Links35368
Node: Tips36055
Node: Changelog36373
Node: 07-pre37111
Node: 0637481
Node: 05240495
Node: 05140795
Node: 0541212
Node: 04942686
Node: 04842960
Node: 04743307
Node: 04643702
Node: 04544102
Node: 04444463
Node: 04344822
Node: 04245019
Node: 04145180
Node: 0445421
Node: 03249354
Node: 03149733
Node: 0349930
Node: 02352905
Node: 02253133
Node: 02153401
Node: 0253600
Node: 0157635
Node: Notes57736
Node: Comparison with Org Agenda searches57898
Node: org-sidebar58770
Node: License59049

End Tag Table

View file

@ -245,6 +245,13 @@ with keyword arg NOW in PLIST."
:to-equal '(link :description "DESCRIPTION" :target "TARGET"
:regexp-p t))))
(describe "(logbook)"
(it "with only string argument"
(expect (org-ql--normalize-query '(logbook "String ending in a period."))
:to-equal '(logbook "String ending in a period\\\."))
(expect (org-ql--query-string-to-sexp "logbook:called")
:to-equal '(logbook "called"))))
(describe "(outline-path)"
(it "with a regexp metacharacter"
;; Ensures that normalizer doesn't infinitely loop.