summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Goaziou <mail@nicolasgoaziou.fr>2017-02-08 22:24:32 +0100
committerNicolas Goaziou <mail@nicolasgoaziou.fr>2017-02-13 14:41:15 +0100
commit7e8cf5f4c202f51231d444f41735a4db06cb7052 (patch)
treefd9501833710815c1283908df620837ada7d0a4e
parent1d39286183f82a102975001329eb0df00b7996d0 (diff)
downloadorg-mode-7e8cf5f4c202f51231d444f41735a4db06cb7052.tar.gz
Use Org duration library
* contrib/lisp/org-depend.el (org-depend-trigger-todo): Use new functions. * contrib/lisp/org-invoice.el (org-invoice-heading-info): (org-invoice-info-to-table): (org-invoice-list-to-table): Use new functions. * contrib/lisp/ox-taskjuggler.el (org-taskjuggler--build-task): Use new functions. * lisp/org-agenda.el (org-agenda-show-clocking-issues): (org-agenda-format-item): (org-agenda-filter-effort-form): Use new functions. * lisp/org-clock.el (org-clock-get-clock-string): (org-clock-modify-effort-estimate): (org-clock-notify-once-if-expired): (org-clock-out): (org-clock-display): (org-clock-put-overlay): (org-clocktable-write-default): Use new functions. * lisp/org-table.el (org-table-sort-lines): Use new functions. * lisp/org.el (org-properties-postprocess-alist): (org-refresh-effort-properties): (org-set-effort): (org-entry-properties): (org-property-next-allowed-value): Use new functions. (org-time-clocksum-format): (org-time-clocksum-use-fractional): (org-time-clocksum-use-fractional-format): (org-time-clocksum-use-effort-durations): Declare as obsolete. Move to "org-compat.el". (org-minutes-to-clocksum-string): (org-hh:mm-string-to-minutes): (org-duration-string-to-minutes): Declare as obsolete. Move to "org-compat.el". (org-hours-to-clocksum-string): Remove function. * lisp/org-colview.el (org-columns--collect-values): Use new functions. (org-columns--duration-re): Remove variable. (org-columns--time-to-seconds): Rename to... (org-columns--age-to-minutes): ... this. (org-columns--format-age): New function. (org-columns--summary-apply-times): (org-columns--summary-min-age): (org-columns--summary-max-age): (org-columns--summary-mean-age): Use new functions. * testing/lisp/test-org-clock.el (test-org-clock-clocktable-contents-at-point): * testing/lisp/test-org-colview.el (test-org-colview/columns-summary): Update tests.
-rw-r--r--contrib/lisp/org-depend.el2
-rw-r--r--contrib/lisp/org-invoice.el10
-rw-r--r--contrib/lisp/ox-taskjuggler.el2
-rw-r--r--etc/ORG-NEWS37
-rw-r--r--lisp/org-agenda.el38
-rw-r--r--lisp/org-clock.el31
-rw-r--r--lisp/org-colview.el94
-rw-r--r--lisp/org-compat.el22
-rw-r--r--lisp/org-table.el2
-rw-r--r--lisp/org.el269
-rw-r--r--testing/lisp/test-org-clock.el5
-rw-r--r--testing/lisp/test-org-colview.el29
12 files changed, 150 insertions, 391 deletions
diff --git a/contrib/lisp/org-depend.el b/contrib/lisp/org-depend.el
index b6f3d27..cd570c5 100644
--- a/contrib/lisp/org-depend.el
+++ b/contrib/lisp/org-depend.el
@@ -270,7 +270,7 @@ This does two different kinds of triggers:
(effort (when (or effort-up effort-down)
(let ((effort (get-text-property (point) 'org-effort)))
(when effort
- (org-duration-string-to-minutes effort))))))
+ (org-duration-to-minutes effort))))))
(push (list (point) todo-kwd priority tags effort)
items))
(unless (org-goto-sibling)
diff --git a/contrib/lisp/org-invoice.el b/contrib/lisp/org-invoice.el
index 4c83d2e..6868894 100644
--- a/contrib/lisp/org-invoice.el
+++ b/contrib/lisp/org-invoice.el
@@ -55,6 +55,8 @@
(require 'cl)
(require 'org))
+(declare-function org-duration-from-minutes "org-duration" (minutes &optional fmt fractional))
+
(defgroup org-invoice nil
"OrgMode Invoice Helper"
:tag "Org-Invoice" :group 'org)
@@ -159,7 +161,7 @@ looks like tree2, where the level is 2."
(setq title (replace-match "" nil nil title)))
(when (string-match "[ \t]+$" title)
(setq title (replace-match "" nil nil title)))
- (setq work (org-hh:mm-string-to-minutes work))
+ (setq work (org-duration-to-minutes work))
(setq rate (string-to-number rate))
(setq org-invoice-current-item (list (cons 'title title)
(cons 'date date)
@@ -226,8 +228,8 @@ looks like tree2, where the level is 2."
(setq
org-invoice-total-time (+ org-invoice-total-time work)
org-invoice-total-price (+ org-invoice-total-price price)))
- (setq total (and total (org-minutes-to-clocksum-string total)))
- (setq work (and work (org-minutes-to-clocksum-string work)))
+ (setq total (and total (org-duration-from-minutes total)))
+ (setq work (and work (org-duration-from-minutes work)))
(insert-before-markers
(concat "|" title
(cond
@@ -251,7 +253,7 @@ looks like tree2, where the level is 2."
(when with-summary
(insert-before-markers
(concat "|-\n|Total:|"
- (org-minutes-to-clocksum-string org-invoice-total-time)
+ (org-duration-from-minutes org-invoice-total-time)
(and with-price (concat "|" (format "%.2f" org-invoice-total-price)))
"|\n")))))
diff --git a/contrib/lisp/ox-taskjuggler.el b/contrib/lisp/ox-taskjuggler.el
index d856878..2144b04 100644
--- a/contrib/lisp/ox-taskjuggler.el
+++ b/contrib/lisp/ox-taskjuggler.el
@@ -861,7 +861,7 @@ a unique id will be associated to it."
(and complete (format " complete %s\n" complete))
(and effort
(format " effort %s\n"
- (let* ((minutes (org-duration-string-to-minutes effort))
+ (let* ((minutes (org-duration-minutes effort))
(hours (/ minutes 60.0)))
(format "%.1fh" hours))))
(and priority (format " priority %s\n" priority))
diff --git a/etc/ORG-NEWS b/etc/ORG-NEWS
index ad70cc1..4068f41 100644
--- a/etc/ORG-NEWS
+++ b/etc/ORG-NEWS
@@ -12,6 +12,15 @@ Please send Org bug reports to mailto:emacs-orgmode@gnu.org.
** Incompatible changes
+*** Variables relative to clocksum duration are obsolete
+
+~org-time-clocksum-format~, ~org-time-clocksum-use-fractional~ and
+~org-time-clocksum-fractional-format~ are obsolete. If you changed
+them, consider modifying ~org-duration-format~ instead.
+
+Variable ~org-time-clocksum-use-effort-durations~ is also obsolete.
+Consider setting ~org-duration-units~ instead.
+
*** ~org-capture-templates~ no longer accepts S-expressions as file names
Since functions are allowed there, a straightforward way to migrate
@@ -67,11 +76,12 @@ The optional argument is now a string to extract the repeater from.
See docstring for details.
** New features
-*** ~org-edit-special~ can edit LaTeX environments
+*** New Org duration library
+This new library implements tools to read and print time durations in
+various formats (e.g., "H:MM", or "1d 2h 3min"...).
-Using ~C-c '~ on a LaTeX environment opens a sub-editing buffer. By
-default, major mode in that buffer is ~latex-mode~, but it can be
-changed by configuring ~org-src-lang-modes~.
+See ~org-duration-to-minutes~ and ~org-duration-from-minutes~
+docstrings.
*** Agenda
**** New variable : ~org-agenda-show-future-repeats~
@@ -163,6 +173,12 @@ user to specify the name of the output file upon exporting the
document. This also has an effect on publishing.
**** Horizontal rules are no longer ignored in LaTeX table math mode
+*** ~org-edit-special~ can edit LaTeX environments
+
+Using ~C-c '~ on a LaTeX environment opens a sub-editing buffer. By
+default, major mode in that buffer is ~latex-mode~, but it can be
+changed by configuring ~org-src-lang-modes~.
+
*** ~org-list-to-generic~ includes a new property: ~:ifmt~
~:ifmt~ is a function to be called on the body of each item. See
@@ -189,6 +205,19 @@ Use ~org-agenda-skip-if~ instead.
*** ~org-agenda-skip-entry-when-regexp-matches-in-subtree~ is obsolete
Use ~org-agenda-skip-if~ instead.
+
+*** ~org-minutes-to-clocksum-string~ is obsolete
+
+Use ~org-duration-from-minutes~ instead.
+
+*** ~org-hh:mm-string-to-minutes~ is obsolete
+
+Use ~org-duration-to-minutes~ instead.
+
+*** ~org-duration-string-to-minutes~ is obsolete
+
+Use ~org-duration-to-minutes~ instead.
+
** Removed options
*** ~org-agenda-repeating-timestamp-show-all~ is removed.
diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el
index c81221b..4f18f4b 100644
--- a/lisp/org-agenda.el
+++ b/lisp/org-agenda.el
@@ -5746,8 +5746,7 @@ then those holidays will be skipped."
"Add overlays, showing issues with clocking.
See also the user option `org-agenda-clock-consistency-checks'."
(interactive)
- (let* ((org-time-clocksum-use-effort-durations nil)
- (pl org-agenda-clock-consistency-checks)
+ (let* ((pl org-agenda-clock-consistency-checks)
(re (concat "^[ \t]*"
org-clock-string
"[ \t]+"
@@ -5755,14 +5754,14 @@ See also the user option `org-agenda-clock-consistency-checks'."
"\\(-\\{1,3\\}\\(\\[.*?\\]\\)\\)?")) ; group 3 is second
(tlstart 0.)
(tlend 0.)
- (maxtime (org-hh:mm-string-to-minutes
+ (maxtime (org-duration-to-minutes
(or (plist-get pl :max-duration) "24:00")))
- (mintime (org-hh:mm-string-to-minutes
+ (mintime (org-duration-to-minutes
(or (plist-get pl :min-duration) 0)))
- (maxgap (org-hh:mm-string-to-minutes
+ (maxgap (org-duration-to-minutes
;; default 30:00 means never complain
(or (plist-get pl :max-gap) "30:00")))
- (gapok (mapcar 'org-hh:mm-string-to-minutes
+ (gapok (mapcar #'org-duration-to-minutes
(plist-get pl :gap-ok-around)))
(def-face (or (plist-get pl :default-face)
'((:background "DarkRed") (:foreground "white"))))
@@ -5796,14 +5795,12 @@ See also the user option `org-agenda-clock-consistency-checks'."
((> dt (* 60 maxtime))
;; a very long clocking chunk
(setq issue (format "Clocking interval is very long: %s"
- (org-minutes-to-clocksum-string
- (floor (/ (float dt) 60.))))
+ (org-duration-from-minutes (floor (/ dt 60.))))
face (or (plist-get pl :long-face) face)))
((< dt (* 60 mintime))
;; a very short clocking chunk
(setq issue (format "Clocking interval is very short: %s"
- (org-minutes-to-clocksum-string
- (floor (/ (float dt) 60.))))
+ (org-duration-from-minutes (floor (/ dt 60.))))
face (or (plist-get pl :short-face) face)))
((and (> tlend 0) (< ts tlend))
;; Two clock entries are overlapping
@@ -6405,18 +6402,19 @@ Any match of REMOVE-RE will be removed from TXT."
(if s1 (setq s1 (org-get-time-of-day s1 'string t)))
(if s2 (setq s2 (org-get-time-of-day s2 'string t)))
- ;; Try to set s2 if s1 and `org-agenda-default-appointment-duration' are set
- (let (org-time-clocksum-use-effort-durations)
- (when (and s1 (not s2) org-agenda-default-appointment-duration)
- (setq s2
- (org-minutes-to-clocksum-string
- (+ (org-hh:mm-string-to-minutes s1)
- org-agenda-default-appointment-duration)))))
+ ;; Try to set s2 if s1 and
+ ;; `org-agenda-default-appointment-duration' are set
+ (when (and s1 (not s2) org-agenda-default-appointment-duration)
+ (setq s2
+ (org-duration-from-minutes
+ (+ (org-duration-to-minutes s1 t)
+ org-agenda-default-appointment-duration)
+ nil t)))
;; Compute the duration
(when s2
- (setq duration (- (org-hh:mm-string-to-minutes s2)
- (org-hh:mm-string-to-minutes s1)))))
+ (setq duration (- (org-duration-to-minutes s2)
+ (org-duration-to-minutes s1)))))
(when (string-match "\\([ \t]+\\)\\(:[[:alnum:]_@#%:]+:\\)[ \t]*$" txt)
;; Tags are in the string
@@ -7548,7 +7546,7 @@ E looks like \"+<2:25\"."
((equal op ??) op)
(t '=)))
(list 'org-agenda-compare-effort (list 'quote op)
- (org-duration-string-to-minutes e))))
+ (org-duration-to-minutes e))))
(defun org-agenda-compare-effort (op value)
"Compare the effort of the current line with VALUE, using OP.
diff --git a/lisp/org-clock.el b/lisp/org-clock.el
index 26f360c..35dd8a0 100644
--- a/lisp/org-clock.el
+++ b/lisp/org-clock.el
@@ -665,20 +665,19 @@ If an effort estimate was defined for the current item, use
If not, show simply the clocked time like 01:50."
(let ((clocked-time (org-clock-get-clocked-time)))
(if org-clock-effort
- (let* ((effort-in-minutes
- (org-duration-string-to-minutes org-clock-effort))
+ (let* ((effort-in-minutes (org-duration-to-minutes org-clock-effort))
(work-done-str
(propertize
- (org-minutes-to-clocksum-string clocked-time)
+ (org-duration-from-minutes clocked-time)
'face (if (and org-clock-task-overrun (not org-clock-task-overrun-text))
'org-mode-line-clock-overrun 'org-mode-line-clock)))
- (effort-str (org-minutes-to-clocksum-string effort-in-minutes))
+ (effort-str (org-duration-from-minutes effort-in-minutes))
(clockstr (propertize
(concat " [%s/" effort-str
"] (" (replace-regexp-in-string "%" "%%" org-clock-heading) ")")
'face 'org-mode-line-clock)))
(format clockstr work-done-str))
- (propertize (concat " [" (org-minutes-to-clocksum-string clocked-time)
+ (propertize (concat " [" (org-duration-from-minutes clocked-time)
"]" (format " (%s)" org-clock-heading))
'face 'org-mode-line-clock))))
@@ -748,15 +747,15 @@ clocked item, and the value displayed in the mode line."
;; A string. See if it is a delta
(setq sign (string-to-char value))
(if (member sign '(?- ?+))
- (setq current (org-duration-string-to-minutes current)
+ (setq current (org-duration-to-minutes current)
value (substring value 1))
(setq current 0))
- (setq value (org-duration-string-to-minutes value))
+ (setq value (org-duration-to-minutes value))
(if (equal ?- sign)
(setq value (- current value))
(if (equal ?+ sign) (setq value (+ current value)))))
(setq value (max 0 value)
- org-clock-effort (org-minutes-to-clocksum-string value))
+ org-clock-effort (org-duration-from-minutes value))
(org-entry-put org-clock-marker "Effort" org-clock-effort)
(org-clock-update-mode-line)
(message "Effort is now %s" org-clock-effort))
@@ -769,7 +768,7 @@ clocked item, and the value displayed in the mode line."
"Show notification if we spent more time than we estimated before.
Notification is shown only once."
(when (org-clocking-p)
- (let ((effort-in-minutes (org-duration-string-to-minutes org-clock-effort))
+ (let ((effort-in-minutes (org-duration-to-minutes org-clock-effort))
(clocked-time (org-clock-get-clocked-time)))
(if (setq org-clock-task-overrun
(if (or (null effort-in-minutes) (zerop effort-in-minutes))
@@ -1631,7 +1630,7 @@ to, overriding the existing value of `org-clock-out-switch-to-state'."
(org-todo org-clock-out-switch-to-state))))))
(force-mode-line-update)
(message (concat "Clock stopped at %s after "
- (org-minutes-to-clocksum-string (+ (* 60 h) m)) "%s")
+ (org-duration-from-minutes (+ (* 60 h) m)) "%s")
te (if remove " => LINE REMOVED" ""))
(run-hooks 'org-clock-out-hook)
(unless (org-clocking-p)
@@ -1935,7 +1934,7 @@ Use `\\[org-clock-remove-overlays]' to remove the subtree times."
(cond (todayp " for today")
(customp " (custom)")
(t "")))
- (org-minutes-to-clocksum-string
+ (org-duration-from-minutes
org-clock-file-total-minutes)
" (%d hours and %d minutes)")
h m)))
@@ -1960,7 +1959,7 @@ will be easy to remove."
(length (org-get-at-bol 'line-prefix)))) ?ยท)
'(face shadow))
(org-add-props
- (format " %9s " (org-minutes-to-clocksum-string time))
+ (format " %9s " (org-duration-from-minutes time))
'(face org-clock-overlay))
""))
(overlay-put ov 'display tx)
@@ -2463,8 +2462,6 @@ from the dynamic block definition."
(maxlevel (or (plist-get params :maxlevel) 3))
(emph (plist-get params :emphasize))
(level-p (plist-get params :level))
- (org-time-clocksum-use-effort-durations
- (plist-get params :effort-durations))
(timestamp (plist-get params :timestamp))
(properties (plist-get params :properties))
(ntcol (max 1 (or (plist-get params :tcolumns) 100)))
@@ -2558,7 +2555,7 @@ from the dynamic block definition."
(make-string (length properties) ?|) ; properties columns, maybe
(concat (format org-clock-total-time-cell-format (nth 7 lwords)) "| ") ; instead of a headline
(format org-clock-total-time-cell-format
- (org-minutes-to-clocksum-string (or total-time 0))) ;time
+ (org-duration-from-minutes (or total-time 0))) ;time
"|"
(make-string (1- (min maxlevel (or ntcol 100))) ?|)
(cond ((not (eq formula '%)) "")
@@ -2587,7 +2584,7 @@ from the dynamic block definition."
(if level-p "| " "") ; level column, maybe
(if timestamp "| " "") ; timestamp column, maybe
(if properties (make-string (length properties) ?|) "") ;properties columns, maybe
- (org-minutes-to-clocksum-string (nth 1 tbl))))) ; the time
+ (org-duration-from-minutes (nth 1 tbl))))) ; the time
;; Get the list of node entries and iterate over it
(setq entries (nth 2 tbl))
@@ -2619,7 +2616,7 @@ from the dynamic block definition."
(if indent (org-clocktable-indent-string level) "") ; indentation
hlc headline hlc "|" ; headline
(make-string (1- (min ntcol level)) ?|) ; empty fields for higher levels
- hlc (org-minutes-to-clocksum-string (nth 3 entry)) hlc ; time
+ hlc (org-duration-from-minutes (nth 3 entry)) hlc ; time
(make-string (1+ (- maxlevel level)) ?|)
(if (eq formula '%)
(format "%.1f |" (* 100 (/ (nth 3 entry) (float total-time))))
diff --git a/lisp/org-colview.el b/lisp/org-colview.el
index 6a75f70..1d068d3 100644
--- a/lisp/org-colview.el
+++ b/lisp/org-colview.el
@@ -261,7 +261,7 @@ possible to override it with optional argument COMPILED-FMT."
org-agenda-columns-add-appointments-to-effort-sum
(string= p (upcase org-effort-property))
(get-text-property (point) 'duration)
- (propertize (org-minutes-to-clocksum-string
+ (propertize (org-duration-from-minutes
(get-text-property (point) 'duration))
'face 'org-warning))
"")))
@@ -1056,63 +1056,40 @@ This function updates `org-columns-current-fmt-compiled'."
;;;; Column View Summary
-(defconst org-columns--duration-re
- (concat "[0-9.]+ *" (regexp-opt (mapcar #'car org-effort-durations)))
- "Regexp matching a duration.")
-
-(defun org-columns--time-to-seconds (s)
- "Turn time string S into a number of seconds.
-A time is expressed as HH:MM, HH:MM:SS, or with units defined in
-`org-effort-durations'. Plain numbers are considered as hours."
- (cond
- ((string-match-p org-columns--duration-re s)
- (* 60 (org-duration-string-to-minutes s)))
- ((string-match "\\`\\([0-9]+\\):\\([0-9]+\\)\\(?::\\([0-9]+\\)\\)?\\'" s)
- (+ (* 3600 (string-to-number (match-string 1 s)))
- (* 60 (string-to-number (match-string 2 s)))
- (if (match-end 3) (string-to-number (match-string 3 s)) 0)))
- (t (* 3600 (string-to-number s)))))
-
-(defun org-columns--age-to-seconds (s)
- "Turn age string S into a number of seconds.
+(defun org-columns--age-to-minutes (s)
+ "Turn age string S into a number of minutes.
An age is either computed from a given time-stamp, or indicated
-as days/hours/minutes/seconds."
+as a canonical duration, i.e., using units defined in
+`org-duration-canonical-units'."
(cond
((string-match-p org-ts-regexp s)
- (floor
- (- org-columns--time
- (float-time (apply #'encode-time (org-parse-time-string s))))))
- ;; Match own output for computations in upper levels.
- ((string-match "\\([0-9]+\\)d \\([0-9]+\\)h \\([0-9]+\\)m \\([0-9]+\\)s" s)
- (+ (* 86400 (string-to-number (match-string 1 s)))
- (* 3600 (string-to-number (match-string 2 s)))
- (* 60 (string-to-number (match-string 3 s)))
- (string-to-number (match-string 4 s))))
+ (/ (- org-columns--time
+ (float-time (apply #'encode-time (org-parse-time-string s))))
+ 60))
+ ((org-duration-p s) (org-duration-to-minutes s t)) ;skip user units
(t (user-error "Invalid age: %S" s))))
+(defun org-columns--format-age (minutes)
+ "Format MINUTES float as an age string."
+ (org-duration-from-minutes minutes
+ '(("d" . nil) ("h" . nil) ("min" . nil))
+ t)) ;ignore user's custom units
+
(defun org-columns--summary-apply-times (fun times)
"Apply FUN to time values TIMES.
-If TIMES contains any time value expressed as a duration, return
-the result as a duration. If it contains any H:M:S, use that
-format instead. Otherwise, use H:M format."
- (let* ((hms-flag nil)
- (duration-flag nil)
- (seconds
- (apply fun
- (mapcar
- (lambda (time)
- (cond
- (duration-flag)
- ((string-match-p org-columns--duration-re time)
- (setq duration-flag t))
- (hms-flag)
- ((string-match-p "\\`[0-9]+:[0-9]+:[0-9]+\\'" time)
- (setq hms-flag t)))
- (org-columns--time-to-seconds time))
- times))))
- (cond (duration-flag (org-minutes-to-clocksum-string (/ seconds 60.0)))
- (hms-flag (format-seconds "%h:%.2m:%.2s" seconds))
- (t (format-seconds "%h:%.2m" seconds)))))
+Return the result as a duration."
+ (org-duration-from-minutes
+ (apply fun
+ (mapcar (lambda (time)
+ ;; Unlike to `org-duration-to-minutes' standard
+ ;; behavior, we want to consider plain numbers as
+ ;; hours. As a consequence, we treat them
+ ;; differently.
+ (if (string-match-p "\\`[0-9]+\\(?:\\.[0-9]*\\)?\\'" time)
+ (* 60 (string-to-number time))
+ (org-duration-to-minutes time)))
+ times))
+ (org-duration-h:mm-only-p times)))
(defun org-columns--compute-spec (spec &optional update)
"Update tree according to SPEC.
@@ -1271,21 +1248,18 @@ When PRINTF is non-nil, use it to format the result."
(defun org-columns--summary-min-age (ages _)
"Compute the minimum time among AGES."
- (format-seconds
- "%dd %.2hh %mm %ss"
- (apply #'min (mapcar #'org-columns--age-to-seconds ages))))
+ (org-columns--format-age
+ (apply #'min (mapcar #'org-columns--age-to-minutes ages))))
(defun org-columns--summary-max-age (ages _)
"Compute the maximum time among AGES."
- (format-seconds
- "%dd %.2hh %mm %ss"
- (apply #'max (mapcar #'org-columns--age-to-seconds ages))))
+ (org-columns--format-age
+ (apply #'max (mapcar #'org-columns--age-to-minutes ages))))
(defun org-columns--summary-mean-age (ages _)
"Compute the minimum time among AGES."
- (format-seconds
- "%dd %.2hh %mm %ss"
- (/ (apply #'+ (mapcar #'org-columns--age-to-seconds ages))
+ (org-columns--format-age
+ (/ (apply #'+ (mapcar #'org-columns--age-to-minutes ages))
(float (length ages)))))
(defun org-columns--summary-estimate (estimates printf)
diff --git a/lisp/org-compat.el b/lisp/org-compat.el
index 6c6c256..7e3fee7 100644
--- a/lisp/org-compat.el
+++ b/lisp/org-compat.el
@@ -341,6 +341,28 @@ use of this function is for the stuck project list."
(setq skip (re-search-forward org-agenda-skip-regexp end t)))
(and skip entry-end)))
+(define-obsolete-function-alias 'org-minutes-to-clocksum-string
+ 'org-duration-from-minutes "Org 9.1")
+
+(define-obsolete-function-alias 'org-hh:mm-string-to-minutes
+ 'org-duration-to-minutes "Org 9.1")
+
+(define-obsolete-function-alias 'org-duration-string-to-minutes
+ 'org-duration-to-minutes "Org 9.1")
+
+(define-obsolete-variable-alias 'org-time-clocksum-format
+ 'org-duration-format "Org 9.1")
+
+(define-obsolete-variable-alias 'org-time-clocksum-use-fractional
+ 'org-duration-format "Org 9.1")
+
+(define-obsolete-variable-alias 'org-time-clocksum-fractional-format
+ 'org-duration-format "Org 9.1")
+
+(define-obsolete-variable-alias 'org-time-clocksum-use-effort-durations
+ 'org-duration-units "Org 9.1")
+
+
;;;; Obsolete link types
(eval-after-load 'org
diff --git a/lisp/org-table.el b/lisp/org-table.el
index b7a49f3..6a0bf48 100644
--- a/lisp/org-table.el
+++ b/lisp/org-table.el
@@ -1720,7 +1720,7 @@ numeric compare based on the type of the first key in the table."
(float-time
(org-time-string-to-time (match-string 0 f))))
((string-match "[0-9]\\{1,2\\}:[0-9]\\{2\\}" f)
- (org-hh:mm-string-to-minutes f))
+ (org-duration-to-minutes (match-string 0 f)))
(t 0))))
((?f ?F)
(or getkey-func
diff --git a/lisp/org.el b/lisp/org.el
index 8155122..61dbad6 100644
--- a/lisp/org.el
+++ b/lisp/org.el
@@ -3250,135 +3250,6 @@ commands, if custom time display is turned on at the time of export."
(concat "[" (substring f 1 -1) "]")
f)))
-(defcustom org-time-clocksum-format
- '(:days "%dd " :hours "%d" :require-hours t :minutes ":%02d" :require-minutes t)
- "The format string used when creating CLOCKSUM lines.
-This is also used when Org mode generates a time duration.
-
-The value can be a single format string containing two
-%-sequences, which will be filled with the number of hours and
-minutes in that order.
-
-Alternatively, the value can be a plist associating any of the
-keys :years, :months, :weeks, :days, :hours or :minutes with
-format strings. The time duration is formatted using only the
-time components that are needed and concatenating the results.
-If a time unit in absent, it falls back to the next smallest
-unit.
-
-The keys :require-years, :require-months, :require-days,
-:require-weeks, :require-hours, :require-minutes are also
-meaningful. A non-nil value for these keys indicates that the
-corresponding time component should always be included, even if
-its value is 0.
-
-
-For example,
-
- (:days \"%dd\" :hours \"%d\" :require-hours t :minutes \":%02d\"
- :require-minutes t)
-
-means durations longer than a day will be expressed in days,
-hours and minutes, and durations less than a day will always be
-expressed in hours and minutes (even for durations less than an
-hour).
-
-The value
-
- (:days \"%dd\" :minutes \"%dm\")
-
-means durations longer than a day will be expressed in days and
-minutes, and durations less than a day will be expressed entirely
-in minutes (even for durations longer than an hour)."
- :group 'org-time
- :group 'org-clock
- :version "24.4"
- :package-version '(Org . "8.0")
- :type '(choice (string :tag "Format string")
- (set :tag "Plist"
- (group :inline t (const :tag "Years" :years)
- (string :tag "Format string"))
- (group :inline t
- (const :tag "Always show years" :require-years)
- (const t))
- (group :inline t (const :tag "Months" :months)
- (string :tag "Format string"))
- (group :inline t
- (const :tag "Always show months" :require-months)
- (const t))
- (group :inline t (const :tag "Weeks" :weeks)
- (string :tag "Format string"))
- (group :inline t
- (const :tag "Always show weeks" :require-weeks)
- (const t))
- (group :inline t (const :tag "Days" :days)
- (string :tag "Format string"))
- (group :inline t
- (const :tag "Always show days" :require-days)
- (const t))
- (group :inline t (const :tag "Hours" :hours)
- (string :tag "Format string"))
- (group :inline t
- (const :tag "Always show hours" :require-hours)
- (const t))
- (group :inline t (const :tag "Minutes" :minutes)
- (string :tag "Format string"))
- (group :inline t
- (const :tag "Always show minutes" :require-minutes)
- (const t)))))
-
-(defcustom org-time-clocksum-use-fractional nil
- "When non-nil, `\\[org-clock-display]' uses fractional times.
-See `org-time-clocksum-format' for more on time clock formats."
- :group 'org-time
- :group 'org-clock
- :version "24.3"
- :type 'boolean)
-
-(defcustom org-time-clocksum-use-effort-durations nil
- "When non-nil, `\\[org-clock-display]' uses effort durations.
-E.g. by default, one day is considered to be a 8 hours effort,
-so a task that has been clocked for 16 hours will be displayed
-as during 2 days in the clock display or in the clocktable.
-
-See `org-effort-durations' on how to set effort durations
-and `org-time-clocksum-format' for more on time clock formats."
- :group 'org-time
- :group 'org-clock
- :version "24.4"
- :package-version '(Org . "8.0")
- :type 'boolean)
-
-(defcustom org-time-clocksum-fractional-format "%.2f"
- "The format string used when creating CLOCKSUM lines,
-or when Org mode generates a time duration, if
-`org-time-clocksum-use-fractional' is enabled.
-
-The value can be a single format string containing one
-%-sequence, which will be filled with the number of hours as
-a float.
-
-Alternatively, the value can be a plist associating any of the
-keys :years, :months, :weeks, :days, :hours or :minutes with
-a format string. The time duration is formatted using the
-largest time unit which gives a non-zero integer part. If all
-specified formats have zero integer part, the smallest time unit
-is used."
- :group 'org-time
- :type '(choice (string :tag "Format string")
- (set (group :inline t (const :tag "Years" :years)
- (string :tag "Format string"))
- (group :inline t (const :tag "Months" :months)
- (string :tag "Format string"))
- (group :inline t (const :tag "Weeks" :weeks)
- (string :tag "Format string"))
- (group :inline t (const :tag "Days" :days)
- (string :tag "Format string"))
- (group :inline t (const :tag "Hours" :hours)
- (string :tag "Format string"))
- (group :inline t (const :tag "Minutes" :minutes)
- (string :tag "Format string")))))
-
(defcustom org-deadline-warning-days 14
"Number of days before expiration during which a deadline becomes active.
This variable governs the display in sparse trees and in the agenda.
@@ -3789,7 +3660,7 @@ and the clock summary:
((\"Remaining\" (lambda(value)
(let ((clocksum (org-clock-sum-current-item))
- (effort (org-duration-string-to-minutes
+ (effort (org-duration-to-minutes
(org-entry-get (point) \"Effort\"))))
(org-minutes-to-clocksum-string (- effort clocksum))))))"
:group 'org-properties
@@ -9744,7 +9615,7 @@ sub-tree if optional argument INHERIT is non-nil."
(org-refresh-properties
org-effort-property
'((effort . identity)
- (effort-minutes . org-duration-string-to-minutes))))
+ (effort-minutes . org-duration-to-minutes))))
;;;; Link Stuff
@@ -15725,7 +15596,7 @@ When INCREMENT is non-nil, set the property to the next allowed value."
(org-entry-put nil prop val))
(org-refresh-property
'((effort . identity)
- (effort-minutes . org-duration-string-to-minutes))
+ (effort-minutes . org-duration-to-minutes))
val)
(when (equal heading (bound-and-true-p org-clock-current-task))
(setq org-clock-effort (get-text-property (point-at-bol) 'effort))
@@ -15763,8 +15634,7 @@ strings."
(when (or (not specific) (string= specific "CLOCKSUM"))
(let ((clocksum (get-text-property (point) :org-clock-minutes)))
(when clocksum
- (push (cons "CLOCKSUM"
- (org-minutes-to-clocksum-string clocksum))
+ (push (cons "CLOCKSUM" (org-duration-from-minutes clocksum))
props)))
(when specific (throw 'exit props)))
(when (or (not specific) (string= specific "CLOCKSUM_T"))
@@ -15772,7 +15642,7 @@ strings."
:org-clock-minutes-today)))
(when clocksumt
(push (cons "CLOCKSUM_T"
- (org-minutes-to-clocksum-string clocksumt))
+ (org-duration-from-minutes clocksumt))
props)))
(when specific (throw 'exit props)))
(when (or (not specific) (string= specific "ITEM"))
@@ -16607,7 +16477,7 @@ completion."
(when (equal prop org-effort-property)
(org-refresh-property
'((effort . identity)
- (effort-minutes . org-duration-string-to-minutes))
+ (effort-minutes . org-duration-to-minutes))
nval)
(when (string= org-clock-current-task heading)
(setq org-clock-effort nval)
@@ -18316,113 +18186,6 @@ effort string \"2hours\" is equivalent to 120 minutes."
:type '(alist :key-type (string :tag "Modifier")
:value-type (number :tag "Minutes")))
-(defun org-minutes-to-clocksum-string (m)
- "Format number of minutes as a clocksum string.
-The format is determined by `org-time-clocksum-format',
-`org-time-clocksum-use-fractional' and
-`org-time-clocksum-fractional-format' and
-`org-time-clocksum-use-effort-durations'."
- (let ((clocksum "")
- (m (round m)) ; Don't allow fractions of minutes
- h d w mo y fmt n)
- (setq h (if org-time-clocksum-use-effort-durations
- (cdr (assoc "h" org-effort-durations)) 60)
- d (if org-time-clocksum-use-effort-durations
- (/ (cdr (assoc "d" org-effort-durations)) h) 24)
- w (if org-time-clocksum-use-effort-durations
- (/ (cdr (assoc "w" org-effort-durations)) (* d h)) 7)
- mo (if org-time-clocksum-use-effort-durations
- (/ (cdr (assoc "m" org-effort-durations)) (* d h)) 30)
- y (if org-time-clocksum-use-effort-durations
- (/ (cdr (assoc "y" org-effort-durations)) (* d h)) 365))
- ;; fractional format
- (if org-time-clocksum-use-fractional
- (cond
- ;; single format string
- ((stringp org-time-clocksum-fractional-format)
- (format org-time-clocksum-fractional-format (/ m (float h))))
- ;; choice of fractional formats for different time units
- ((and (setq fmt (plist-get org-time-clocksum-fractional-format :years))
- (> (/ (truncate m) (* y d h)) 0))
- (format fmt (/ m (* y d (float h)))))
- ((and (setq fmt (plist-get org-time-clocksum-fractional-format :months))
- (> (/ (truncate m) (* mo d h)) 0))
- (format fmt (/ m (* mo d (float h)))))
- ((and (setq fmt (plist-get org-time-clocksum-fractional-format :weeks))
- (> (/ (truncate m) (* w d h)) 0))
- (format fmt (/ m (* w d (float h)))))
- ((and (setq fmt (plist-get org-time-clocksum-fractional-format :days))
- (> (/ (truncate m) (* d h)) 0))
- (format fmt (/ m (* d (float h)))))
- ((and (setq fmt (plist-get org-time-clocksum-fractional-format :hours))
- (> (/ (truncate m) h) 0))
- (format fmt (/ m (float h))))
- ((setq fmt (plist-get org-time-clocksum-fractional-format :minutes))
- (format fmt m))
- ;; fall back to smallest time unit with a format
- ((setq fmt (plist-get org-time-clocksum-fractional-format :hours))
- (format fmt (/ m (float h))))
- ((setq fmt (plist-get org-time-clocksum-fractional-format :days))
- (format fmt (/ m (* d (float h)))))
- ((setq fmt (plist-get org-time-clocksum-fractional-format :weeks))
- (format fmt (/ m (* w d (float h)))))
- ((setq fmt (plist-get org-time-clocksum-fractional-format :months))
- (format fmt (/ m (* mo d (float h)))))
- ((setq fmt (plist-get org-time-clocksum-fractional-format :years))
- (format fmt (/ m (* y d (float h))))))
- ;; standard (non-fractional) format, with single format string
- (if (stringp org-time-clocksum-format)
- (format org-time-clocksum-format (setq n (/ m h)) (- m (* h n)))
- ;; separate formats components
- (and (setq fmt (plist-get org-time-clocksum-format :years))
- (or (> (setq n (/ (truncate m) (* y d h))) 0)
- (plist-get org-time-clocksum-format :require-years))
- (setq clocksum (concat clocksum (format fmt n))
- m (- m (* n y d h))))
- (and (setq fmt (plist-get org-time-clocksum-format :months))
- (or (> (setq n (/ (truncate m) (* mo d h))) 0)
- (plist-get org-time-clocksum-format :require-months))
- (setq clocksum (concat clocksum (format fmt n))
- m (- m (* n mo d h))))
- (and (setq fmt (plist-get org-time-clocksum-format :weeks))
- (or (> (setq n (/ (truncate m) (* w d h))) 0)
- (plist-get org-time-clocksum-format :require-weeks))
- (setq clocksum (concat clocksum (format fmt n))
- m (- m (* n w d h))))
- (and (setq fmt (plist-get org-time-clocksum-format :days))
- (or (> (setq n (/ (truncate m) (* d h))) 0)
- (plist-get org-time-clocksum-format :require-days))
- (setq clocksum (concat clocksum (format fmt n))
- m (- m (* n d h))))
- (and (setq fmt (plist-get org-time-clocksum-format :hours))
- (or (> (setq n (/ (truncate m) h)) 0)
- (plist-get org-time-clocksum-format :require-hours))
- (setq clocksum (concat clocksum (format fmt n))
- m (- m (* n h))))
- (and (setq fmt (plist-get org-time-clocksum-format :minutes))
- (or (> m 0) (plist-get org-time-clocksum-format :require-minutes))
- (setq clocksum (concat clocksum (format fmt m))))
- ;; return formatted time duration
- clocksum))))
-
-(defun org-hours-to-clocksum-string (n)
- (org-minutes-to-clocksum-string (* n 60)))
-
-(defun org-hh:mm-string-to-minutes (s)
- "Convert a string H:MM to a number of minutes.
-If the string is just a number, interpret it as minutes.
-In fact, the first hh:mm or number in the string will be taken,
-there can be extra stuff in the string.
-If no number is found, the return value is 0."
- (cond
- ((integerp s) s)
- ((string-match "\\([0-9]+\\):\\([0-9]+\\)" s)
- (+ (* (string-to-number (match-string 1 s)) 60)
- (string-to-number (match-string 2 s))))
- ((string-match "\\([0-9]+\\)" s)
- (string-to-number (match-string 1 s)))
- (t 0)))
-
(defcustom org-image-actual-width t
"Should we use the actual width of images when inlining them?
@@ -18477,26 +18240,6 @@ The value is a list, with zero or more of the symbols `effort', `appt',
:package-version '(Org . "8.3")
:group 'org-agenda)
-(defun org-duration-string-to-minutes (s &optional output-to-string)
- "Convert a duration string S to minutes.
-
-A bare number is interpreted as minutes, modifiers can be set by
-customizing `org-effort-durations' (which see).
-
-Entries containing a colon are interpreted as H:MM by
-`org-hh:mm-string-to-minutes'."
- (let ((result 0)
- (re (concat "\\([0-9.]+\\) *\\("
- (regexp-opt (mapcar 'car org-effort-durations))
- "\\)")))
- (while (string-match re s)
- (cl-incf result (* (cdr (assoc (match-string 2 s) org-effort-durations))
- (string-to-number (match-string 1 s))))
- (setq s (replace-match "" nil t s)))
- (setq result (floor result))
- (cl-incf result (org-hh:mm-string-to-minutes s))
- (if output-to-string (number-to-string result) result)))
-
;;;; Files
(defun org-save-all-org-buffers ()
diff --git a/testing/lisp/test-org-clock.el b/testing/lisp/test-org-clock.el
index e0f23ea..60b32eb 100644
--- a/testing/lisp/test-org-clock.el
+++ b/testing/lisp/test-org-clock.el
@@ -67,10 +67,7 @@ contents. The clocktable doesn't appear in the buffer."
(insert "#+END:\n"))
(unwind-protect
(save-excursion
- (let ((org-time-clocksum-format
- '(:hours "%d" :require-hours t :minutes ":%02d"
- :require-minutes t)))
- (org-update-dblock))
+ (let ((org-duration-format 'h:mm)) (org-update-dblock))
(forward-line)
;; Skip caption.
(when (looking-at "#\\+CAPTION:") (forward-line))
diff --git a/testing/lisp/test-org-colview.el b/testing/lisp/test-org-colview.el
index 8b312ab..1e42c12 100644
--- a/testing/lisp/test-org-colview.el
+++ b/testing/lisp/test-org-colview.el
@@ -415,7 +415,7 @@
;; {@min}, {@max} and {@mean} apply to ages.
(should
(equal
- "0d 00h 0m 0s"
+ "0min"
(cl-letf (((symbol-function 'current-time)
(lambda ()
(apply #'encode-time
@@ -434,7 +434,7 @@
(get-char-property (point) 'org-columns-value-modified)))))
(should
(equal
- "705d 01h 0m 0s"
+ "705d 1h"
(cl-letf (((symbol-function 'current-time)
(lambda ()
(apply #'encode-time
@@ -453,7 +453,7 @@
(get-char-property (point) 'org-columns-value-modified)))))
(should
(equal
- "352d 12h 30m 0s"
+ "352d 12h 30min"
(cl-letf (((symbol-function 'current-time)
(lambda ()
(apply #'encode-time
@@ -475,7 +475,7 @@
;; combinations of duration and H:MM:SS patterns.
(should
(equal
- "1d 4:20"
+ "3d 4:20"
(org-test-with-temp-text
"* H
** S1
@@ -487,9 +487,8 @@
:A: 1:20
:END:"
(let ((org-columns-default-format "%A{:}")
- (org-time-clocksum-use-fractional nil)
- (org-time-clocksum-format
- '(:days "%dd " :hours "%d" :minutes ":%02d")))
+ (org-duration-units '(("d" . 1440) ("h" . 60)))
+ (org-duration-format '(("d" . nil) (special . h:mm))))
(org-columns))
(get-char-property (point) 'org-columns-value-modified))))
(should
@@ -509,7 +508,7 @@
(get-char-property (point) 'org-columns-value-modified))))
(should
(equal
- "1d 4:20"
+ "3d 4:20"
(org-test-with-temp-text
"* H
** S1
@@ -521,25 +520,23 @@
:A: 0d 1:20
:END:"
(let ((org-columns-default-format "%A{:}")
- (org-time-clocksum-use-fractional nil)
- (org-time-clocksum-format
- '(:days "%dd " :hours "%d" :minutes ":%02d")))
+ (org-duration-units '(("d" . 1440) ("h" . 60)))
+ (org-duration-format '(("d" . nil) (special . h:mm))))
(org-columns))
(get-char-property (point) 'org-columns-value-modified))))
- ;; @min, @max and @mean also accept regular duration in
- ;; a "?d ?h ?m ?s" format.
+ ;; @min, @max and @mean also accept regular duration.
(should
(equal
- "1d 10h 0m 0s"
+ "1d 10h"
(org-test-with-temp-text
"* H
** S1
:PROPERTIES:
-:A: 1d 10h 0m 0s
+:A: 1d 10h 0min
:END:
** S1
:PROPERTIES:
-:A: 5d 3h 0m 0s
+:A: 5d 3h
:END:"
(let ((org-columns-default-format "%A{@min}")) (org-columns))
(get-char-property (point) 'org-columns-value-modified))))