summaryrefslogtreecommitdiff
path: root/lisp/org/org-clock.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/org/org-clock.el')
-rw-r--r--lisp/org/org-clock.el204
1 files changed, 101 insertions, 103 deletions
diff --git a/lisp/org/org-clock.el b/lisp/org/org-clock.el
index 7d7640db588..8df185d2e91 100644
--- a/lisp/org/org-clock.el
+++ b/lisp/org/org-clock.el
@@ -39,7 +39,6 @@
(defvar org-frame-title-format-backup frame-title-format)
(defvar org-time-stamp-formats)
-(defvar org-ts-what)
(defgroup org-clock nil
@@ -523,6 +522,16 @@ of a different task.")
(define-key org-clock-mode-line-map [mode-line mouse-2] 'org-clock-goto)
(define-key org-clock-mode-line-map [mode-line mouse-1] 'org-clock-menu)
+(defun org-clock--translate (s language)
+ "Translate string S into using string LANGUAGE.
+Assume S in the English term to translate. Return S as-is if it
+cannot be translated."
+ (or (nth (pcase s
+ ("File" 1) ("L" 2) ("Timestamp" 3) ("Headline" 4) ("Time" 5)
+ ("ALL" 6) ("Total time" 7) ("File time" 8) ("Clock summary at" 9))
+ (assoc-string language org-clock-clocktable-language-setup t))
+ s))
+
(defun org-clock-menu ()
(interactive)
(popup-menu
@@ -582,8 +591,9 @@ of a different task.")
"Hook called in task selection just before prompting the user.")
(defun org-clock-select-task (&optional prompt)
- "Select a task that was recently associated with clocking."
- (interactive)
+ "Select a task that was recently associated with clocking.
+Return marker position of the selected task. Raise an error if
+there is no recent clock to choose from."
(let (och chl sel-list rpl (i 0) s)
;; Remove successive dups from the clock history to consider
(dolist (c org-clock-history)
@@ -668,20 +678,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))))
@@ -751,15 +760,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))
@@ -772,7 +781,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))
@@ -1193,9 +1202,7 @@ time as the start time. See `org-clock-continuously' to make this
the default behavior."
(interactive "P")
(setq org-clock-notification-was-shown nil)
- (org-refresh-properties
- org-effort-property '((effort . identity)
- (effort-minutes . org-duration-string-to-minutes)))
+ (org-refresh-effort-properties)
(catch 'abort
(let ((interrupting (and (not org-clock-resolving-clocks-due-to-idleness)
(org-clocking-p)))
@@ -1620,8 +1627,7 @@ to, overriding the existing value of `org-clock-out-switch-to-state'."
(when org-clock-out-switch-to-state
(save-excursion
(org-back-to-heading t)
- (let ((org-inhibit-logging t)
- (org-clock-out-when-done nil))
+ (let ((org-clock-out-when-done nil))
(cond
((functionp org-clock-out-switch-to-state)
(let ((case-fold-search nil))
@@ -1636,7 +1642,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)
@@ -1674,11 +1680,11 @@ Optional argument N tells to change by that many units."
"Change CLOCK timestamps synchronously at cursor.
UPDOWN tells whether to change `up' or `down'.
Optional argument N tells to change by that many units."
- (setq org-ts-what nil)
- (when (org-at-timestamp-p t)
- (let ((tschange (if (eq updown 'up) 'org-timestamp-up
- 'org-timestamp-down))
- ts1 begts1 ts2 begts2 updatets1 tdiff)
+ (let ((tschange (if (eq updown 'up) 'org-timestamp-up
+ 'org-timestamp-down))
+ (timestamp? (org-at-timestamp-p 'lax))
+ ts1 begts1 ts2 begts2 updatets1 tdiff)
+ (when timestamp?
(save-excursion
(move-beginning-of-line 1)
(re-search-forward org-ts-regexp3 nil t)
@@ -1690,24 +1696,24 @@ Optional argument N tells to change by that many units."
(if (not ts2)
;; fall back on org-timestamp-up if there is only one
(funcall tschange n)
- ;; setq this so that (boundp 'org-ts-what is non-nil)
(funcall tschange n)
(let ((ts (if updatets1 ts2 ts1))
(begts (if updatets1 begts1 begts2)))
(setq tdiff
(time-subtract
- (org-time-string-to-time org-last-changed-timestamp)
- (org-time-string-to-time ts)))
+ (org-time-string-to-time org-last-changed-timestamp t)
+ (org-time-string-to-time ts t)))
(save-excursion
(goto-char begts)
(org-timestamp-change
(round (/ (float-time tdiff)
- (cond ((eq org-ts-what 'minute) 60)
- ((eq org-ts-what 'hour) 3600)
- ((eq org-ts-what 'day) (* 24 3600))
- ((eq org-ts-what 'month) (* 24 3600 31))
- ((eq org-ts-what 'year) (* 24 3600 365.2)))))
- org-ts-what 'updown)))))))
+ (pcase timestamp?
+ (`minute 60)
+ (`hour 3600)
+ (`day (* 24 3600))
+ (`month (* 24 3600 31))
+ (`year (* 24 3600 365.2)))))
+ timestamp? 'updown)))))))
;;;###autoload
(defun org-clock-cancel ()
@@ -1942,7 +1948,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)))
@@ -1968,7 +1974,7 @@ will be easy to remove."
?\ยท)
'(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)
@@ -2376,6 +2382,7 @@ the currently selected interval size."
(`file-with-archives
(and buffer-file-name
(org-add-archive-files (list buffer-file-name))))
+ ((pred functionp) (funcall scope))
((pred consp) scope)
(_ (or (buffer-file-name) (current-buffer)))))
(block (plist-get params :block))
@@ -2456,20 +2463,12 @@ from the dynamic block definition."
;; someone wants to write their own special formatter, this maybe
;; much easier because there can be a fixed format with a
;; well-defined number of columns...
- (let* ((hlchars '((1 . "*") (2 . "/")))
- (lwords (assoc (or (plist-get params :lang)
- (bound-and-true-p org-export-default-language)
- "en")
- org-clock-clocktable-language-setup))
+ (let* ((lang (or (plist-get params :lang) "en"))
(multifile (plist-get params :multifile))
(block (plist-get params :block))
(sort (plist-get params :sort))
(header (plist-get params :header))
- (ws (or (plist-get params :wstart) 1))
- (ms (or (plist-get params :mstart) 1))
(link (plist-get params :link))
- (org-time-clocksum-use-effort-durations
- (plist-get params :effort-durations))
(maxlevel (or (plist-get params :maxlevel) 3))
(emph (plist-get params :emphasize))
(compact? (plist-get params :compact))
@@ -2494,49 +2493,40 @@ from the dynamic block definition."
(indent (or compact? (plist-get params :indent)))
(formula (plist-get params :formula))
(case-fold-search t)
- range-text total-time recalc narrow-cut-p)
+ (total-time (apply #'+ (mapcar #'cadr tables)))
+ recalc narrow-cut-p)
(when (and narrow (integerp narrow) link)
;; We cannot have both integer narrow and link.
- (message
- "Using hard narrowing in clocktable to allow for links")
+ (message "Using hard narrowing in clocktable to allow for links")
(setq narrow (intern (format "%d!" narrow))))
- (when narrow
- (cond
- ((integerp narrow))
- ((and (symbolp narrow)
- (string-match "\\`[0-9]+!\\'" (symbol-name narrow)))
- (setq narrow-cut-p t
- narrow (string-to-number (substring (symbol-name narrow)
- 0 -1))))
- (t
- (error "Invalid value %s of :narrow property in clock table"
- narrow))))
-
- (when block
- ;; Get the range text for the header.
- (setq range-text (nth 2 (org-clock-special-range block nil t ws ms))))
-
- ;; Compute the total time.
- (setq total-time (apply #'+ (mapcar #'cadr tables)))
+ (pcase narrow
+ ((or `nil (pred integerp)) nil) ;nothing to do
+ ((and (pred symbolp)
+ (guard (string-match-p "\\`[0-9]+!\\'" (symbol-name narrow))))
+ (setq narrow-cut-p t)
+ (setq narrow (string-to-number (symbol-name narrow))))
+ (_ (error "Invalid value %s of :narrow property in clock table" narrow)))
- ;; Now we need to output this tsuff.
+ ;; Now we need to output this table stuff.
(goto-char ipos)
;; Insert the text *before* the actual table.
(insert-before-markers
(or header
;; Format the standard header.
- (concat
- "#+CAPTION: "
- (nth 9 lwords) " ["
- (substring
- (format-time-string (cdr org-time-stamp-formats))
- 1 -1)
- "]"
- (if block (concat ", for " range-text ".") "")
- "\n")))
+ (format "#+CAPTION: %s %s%s\n"
+ (org-clock--translate "Clock summary at" lang)
+ (format-time-string (org-time-stamp-format t t))
+ (if block
+ (let ((range-text
+ (nth 2 (org-clock-special-range
+ block nil t
+ (plist-get params :wstart)
+ (plist-get params :mstart)))))
+ (format ", for %s." range-text))
+ ""))))
;; Insert the narrowing line
(when (and narrow (integerp narrow) (not narrow-cut-p))
@@ -2545,36 +2535,45 @@ from the dynamic block definition."
(if multifile "|" "") ;file column, maybe
(if level? "|" "") ;level column, maybe
(if timestamp "|" "") ;timestamp column, maybe
- (if properties (make-string (length properties) ?|) "") ;properties columns, maybe
- (format "<%d>| |\n" narrow))) ; headline and time columns
+ (if properties ;properties columns, maybe
+ (make-string (length properties) ?|)
+ "")
+ (format "<%d>| |\n" narrow))) ;headline and time columns
;; Insert the table header line
(insert-before-markers
- "|" ;table line starter
- (if multifile (concat (nth 1 lwords) "|") "") ;file column, maybe
- (if level? (concat (nth 2 lwords) "|") "") ;level column, maybe
- (if timestamp (concat (nth 3 lwords) "|") "") ;timestamp column, maybe
+ "|" ;table line starter
+ (if multifile ;file column, maybe
+ (concat (org-clock--translate "File" lang) "|")
+ "")
+ (if level? ;level column, maybe
+ (concat (org-clock--translate "L" lang) "|")
+ "")
+ (if timestamp ;timestamp column, maybe
+ (concat (org-clock--translate "Timestamp" lang) "|")
+ "")
(if properties ;properties columns, maybe
(concat (mapconcat #'identity properties "|") "|")
"")
- (concat (nth 4 lwords) "|") ;headline
- (concat (nth 5 lwords) "|") ;time column
- (make-string (max 0 (1- time-columns)) ?|) ;other time columns
+ (concat (org-clock--translate "Headline" lang)"|")
+ (concat (org-clock--translate "Time" lang) "|")
+ (make-string (max 0 (1- time-columns)) ?|) ;other time columns
(if (eq formula '%) "%|\n" "\n"))
;; Insert the total time in the table
(insert-before-markers
"|-\n" ;a hline
"|" ;table line starter
- (if multifile (concat "| " (nth 6 lwords) " ") "")
+ (if multifile (format "| %s " (org-clock--translate "ALL" lang)) "")
;file column, maybe
- (if level? "|" "") ;level column, maybe
- (if timestamp "|" "") ;timestamp column, maybe
+ (if level? "|" "") ;level column, maybe
+ (if timestamp "|" "") ;timestamp column, maybe
(make-string (length properties) ?|) ;properties columns, maybe
- (concat (format org-clock-total-time-cell-format (nth 7 lwords))
+ (concat (format org-clock-total-time-cell-format
+ (org-clock--translate "Total time" lang))
"| ")
(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 (max 0 (1- time-columns)) ?|)
(cond ((not (eq formula '%)) "")
@@ -2595,7 +2594,7 @@ from the dynamic block definition."
(insert-before-markers
(format (concat "| %s %s | %s%s"
(format org-clock-file-time-cell-format
- (nth 8 lwords))
+ (org-clock--translate "File time" lang))
" | *%s*|\n")
(file-name-nondirectory file-name)
(if level? "| " "") ;level column, maybe
@@ -2603,7 +2602,7 @@ from the dynamic block definition."
(if properties ;properties columns, maybe
(make-string (length properties) ?|)
"")
- (org-minutes-to-clocksum-string file-time)))) ;time
+ (org-duration-from-minutes file-time)))) ;time
;; Get the list of node entries and iterate over it
(when (> maxlevel 0)
@@ -2619,15 +2618,18 @@ from the dynamic block definition."
(org-shorten-string (match-string 3 headline)
narrow))
(org-shorten-string headline narrow))))
- (let ((hlc (if emph (or (cdr (assoc level hlchars)) "") "")))
+ (cl-flet ((format-field (f) (format (cond ((not emph) "%s |")
+ ((= level 1) "*%s* |")
+ ((= level 2) "/%s/ |")
+ (t "%s |"))
+ f)))
(insert-before-markers
"|" ;start the table line
(if multifile "|" "") ;free space for file name column?
(if level? (format "%d|" level) "") ;level, maybe
(if timestamp (concat ts "|") "") ;timestamp, maybe
(if properties ;properties columns, maybe
- (concat (mapconcat (lambda (p)
- (or (cdr (assoc p props)) ""))
+ (concat (mapconcat (lambda (p) (or (cdr (assoc p props)) ""))
properties
"|")
"|")
@@ -2635,10 +2637,10 @@ from the dynamic block definition."
(if indent ;indentation
(org-clocktable-indent-string level)
"")
- hlc headline hlc "|" ;headline
+ (format-field headline)
;; Empty fields for higher levels.
(make-string (max 0 (1- (min time-columns level))) ?|)
- hlc (org-minutes-to-clocksum-string time) hlc "|" ; time
+ (format-field (org-duration-from-minutes time))
(make-string (max 0 (- time-columns level)) ?|)
(if (eq formula '%)
(format "%.1f |" (* 100 (/ time (float total-time))))
@@ -2814,9 +2816,7 @@ PROPERTIES: The list properties specified in the `:properties' parameter
(when (and time (> time 0) (org-at-heading-p))
(let ((level (org-reduced-level (org-current-level))))
(when (<= level maxlevel)
- (let* ((headline (replace-regexp-in-string
- (format "\\`%s[ \t]+" org-comment-string) ""
- (nth 4 (org-heading-components))))
+ (let* ((headline (org-get-heading t t t t))
(hdl
(if (not link) headline
(let ((search
@@ -2834,11 +2834,9 @@ PROPERTIES: The list properties specified in the `:properties' parameter
headline)))))))
(tsp
(and timestamp
- (let ((p (org-entry-properties (point) 'special)))
- (or (cdr (assoc "SCHEDULED" p))
- (cdr (assoc "DEADLINE" p))
- (cdr (assoc "TIMESTAMP" p))
- (cdr (assoc "TIMESTAMP_IA" p))))))
+ (cl-some (lambda (p) (org-entry-get (point) p))
+ '("SCHEDULED" "DEADLINE" "TIMESTAMP"
+ "TIMESTAMP_IA"))))
(props
(and properties
(delq nil