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.
This commit is contained in:
John Wiegley 2009-10-16 22:21:13 -04:00
parent cc039d9016
commit defe6c3838
2 changed files with 98 additions and 0 deletions

View File

@ -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.

View File

@ -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.