summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2009-10-16 22:21:13 -0400
committerJohn Wiegley <johnw@newartisans.com>2009-10-16 22:21:13 -0400
commit384d3ebc655ac9ca295ae23978fec0cc5bc55eae (patch)
tree8ab31e9a0721befd5d2c1a69a65373ad0c95c2b4
parent63fbf2aab8968a1674b1bc2cdc0c908bb44cff44 (diff)
downloadorg-mode-384d3ebc655ac9ca295ae23978fec0cc5bc55eae.tar.gz
Added several new utility functions to org-clock
(org-find-open-clocks): New function that returns a list of all open clocks in the given FILE. Note that each clock it returns is a cons cell of the format (MARKER . START-TIME). This "clock" value is used by several of the new clock module utility functions. (org-is-active-clock): New inline function which tests whether the given clock value is the same as the currently active clock. Returns non-nil if this is the case. (org-with-clock-position): New macro that evaluates FORMS with point in the buffer and at the position of the given clock. Changes to the current clock are global. (org-with-clock): New macro that evaluates FORMS with point in the buffer and at the position of the given clock. However, changes to the current clock are local and have no effect on the user's active clock. This allows, for example, far any clock to be cancelled without cancelling the active clock. (org-clock-clock-in): New inline function that switches the active clock to the given clock. If either the argument RESUME, or the global `org-clock-in-resume', are non-nil, it will resume a clock that was previously left open. (org-clock-clock-out): New inline function that clocks out the given clock value without affecting the currently active clock. (org-clock-clock-cancel): New inline function that cancels the given clock value without affecting the currently active clock.
-rwxr-xr-xlisp/ChangeLog25
-rw-r--r--lisp/org-clock.el73
2 files changed, 98 insertions, 0 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index f3c1fa4..59578ad 100755
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,30 @@
2009-10-17 John Wiegley <johnw@newartisans.com>
+ * org-clock.el (org-find-open-clocks): New function that returns a
+ list of all open clocks in the given FILE. Note that each clock
+ it returns is a cons cell of the format (MARKER . START-TIME).
+ This "clock" value is used by several of the new clock module
+ utility functions.
+ (org-is-active-clock): New inline function which tests whether the
+ given clock value is the same as the currently active clock.
+ Returns non-nil if this is the case.
+ (org-with-clock-position): New macro that evaluates FORMS with
+ point in the buffer and at the position of the given clock.
+ Changes to the current clock are global.
+ (org-with-clock): New macro that evaluates FORMS with point in the
+ buffer and at the position of the given clock. However, changes
+ to the current clock are local and have no effect on the user's
+ active clock. This allows, for example, far any clock to be
+ cancelled without cancelling the active clock.
+ (org-clock-clock-in): New inline function that switches the active
+ clock to the given clock. If either the argument RESUME, or the
+ global `org-clock-in-resume', are non-nil, it will resume a clock
+ that was previously left open.
+ (org-clock-clock-out): New inline function that clocks out the
+ given clock value without affecting the currently active clock.
+ (org-clock-clock-cancel): New inline function that cancels the
+ given clock value without affecting the currently active clock.
+
* org-clock.el (org-clock-in): Before creating
`org-clock-mode-line-timer', check to make sure an older timer is
not currently running.
diff --git a/lisp/org-clock.el b/lisp/org-clock.el
index 5518523..5067d2f 100644
--- a/lisp/org-clock.el
+++ b/lisp/org-clock.el
@@ -495,6 +495,79 @@ Use alsa's aplay tool if available."
(defvar org-clock-mode-line-entry nil
"Information for the modeline about the running clock.")
+(defun org-find-open-clocks (file)
+ "Search through the given file and find all open clocks."
+ (let ((buf (or (get-file-buffer file)
+ (find-file-noselect file)))
+ clocks)
+ (with-current-buffer buf
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward "CLOCK: \\(\\[.*?\\]\\)$" nil t)
+ (push (cons (copy-marker (1- (match-end 1)) t)
+ (org-time-string-to-time (match-string 1))) clocks))))
+ clocks))
+
+(defsubst org-is-active-clock (clock)
+ "Return t if CLOCK is the currently active clock."
+ (and (org-clock-is-active)
+ (= org-clock-marker (car clock))))
+
+(defmacro org-with-clock-position (clock &rest forms)
+ "Evaluate FORMS with CLOCK as the current active clock."
+ `(with-current-buffer (marker-buffer (car ,clock))
+ (save-excursion
+ (save-restriction
+ (widen)
+ (goto-char (car ,clock))
+ (beginning-of-line)
+ ,@forms))))
+
+(put 'org-with-clock-position 'lisp-indent-function 1)
+
+(defmacro org-with-clock (clock &rest forms)
+ "Evaluate FORMS with CLOCK as the current active clock.
+This macro also protects the current active clock from being altered."
+ `(org-with-clock-position ,clock
+ (let ((org-clock-start-time (cdr ,clock))
+ (org-clock-total-time)
+ (org-clock-history)
+ (org-clock-effort)
+ (org-clock-marker (car ,clock))
+ (org-clock-hd-marker (save-excursion
+ (outline-back-to-heading t)
+ (point-marker))))
+ ,@forms)))
+
+(put 'org-with-clock 'lisp-indent-function 1)
+
+(defsubst org-clock-clock-in (clock &optional resume)
+ "Clock in to the clock located by CLOCK.
+If necessary, clock-out of the currently active clock."
+ (org-with-clock-position clock
+ (let ((org-clock-in-resume (or resume org-clock-in-resume)))
+ (org-clock-in))))
+
+(defsubst org-clock-clock-out (clock &optional fail-quietly at-time)
+ "Clock out of the clock located by CLOCK."
+ (let ((temp (copy-marker (car clock)
+ (marker-insertion-type (car clock)))))
+ (if (org-is-active-clock clock)
+ (org-clock-out fail-quietly at-time)
+ (org-with-clock clock
+ (org-clock-out fail-quietly at-time)))
+ (setcar clock temp)))
+
+(defsubst org-clock-clock-cancel (clock)
+ "Cancel the clock located by CLOCK."
+ (let ((temp (copy-marker (car clock)
+ (marker-insertion-type (car clock)))))
+ (if (org-is-active-clock clock)
+ (org-clock-cancel)
+ (org-with-clock clock
+ (org-clock-cancel)))
+ (setcar clock temp)))
+
(defun org-clock-in (&optional select)
"Start the clock on the current item.
If necessary, clock-out of the currently active clock.