Using org 6.25e:
Automatically resuming the clock after an Emacs restart fails under the following cases:
1. If org-log-states-order-reversed set to t (default), and a state change line precedes the clock line to resume. Error message is "Cannot restart clock because task does not contain unfinished clock".
Example:
*** STARTED test
:LOGBOOK:
- State "STARTED" from "TODO" [2009-04-09 Thu 13:50]
CLOCK: [2009-04-09 Thu 13:50]
:END:
Reason: point is placed at start of state change line and so fails looking-at test (org-clock.el:345).
Possible solution appears to be to use the existing function org-skip-over-state-notes when looking for the clock line to resume at org-clock.el:343.
2. If org-log-states-order-reversed set to nil. Error message is the same. Reason: point is placed *after* last clock line and so fails looking-at test.
Possible solution: test order-reversed and back up one clock entry before looking-at test.
I have combined these two ideas into a new function (patch attached). I don't imagine I've handled all of the possible configurations of state change entries, log entries, and clock lines, in and out of drawers, so this will probably serve more as a basis for a solution than a solution itself.
(If nothing else, on org-clock.el:346 there's "\\t" where it should be "\t".)
Adam
--- /usr/local/src/org-6.25e/lisp/org-clock.el
2009-04-09 10:27:00.000000000 -0400
+++ org-clock.el
2009-04-09 15:52:12.437500000 -0400
@@ -280,7 +280,7 @@
(interactive "P")
(catch 'abort
(let ((interrupting (marker-buffer org-clock-marker))
-
ts selected-task target-pos)
+
ts selected-task target-pos resume-clock)
(when (equal select '(4))
(setq selected-task (org-clock-select-task "Clock-in on task: "))
(if selected-task
@@ -342,16 +342,14 @@
(org-clock-find-position)
(cond
((and org-clock-in-resume
-
(looking-at
-
(concat "^[ \\t]* " org-clock-string
-
" \\[\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}"
-
" +\\sw+ +[012][0-9]:[0-5][0-9]\\)\\][ \t]*$")))
-
(message "Matched %s" (match-string 1))
-
(setq ts (concat "[" (match-string 1) "]"))
-
(goto-char (match-end 1))
+
(setq resume-clock
+
(org-clock-find-last-clock-from-new-clock-position)))
+
(message "Matched %s" (car resume-clock))
+
(setq ts (concat "[" (car resume-clock) "]"))
+
(goto-char (+ (length (car resume-clock)) (cdr resume-clock)))
(setq org-clock-start-time
(apply 'encode-time
-
(org-parse-time-string (match-string 1)))))
+
(org-parse-time-string (car resume-clock)))))
((eq org-clock-in-resume 'auto-restart)
;; called from org-clock-load during startup,
;; do not interrupt, but warn!
@@ -455,6 +453,29 @@
(and (re-search-forward org-property-end-re nil t)
(goto-char (match-beginning 0))))))))
+(defun org-clock-find-last-clock-from-new-clock-position ()
+ "Attempts to locate last clock line, assuming point is at new
+clock line position (see `org-clock-find-position'). If found,
+moves point to beginning of last clock line and returns a cons
+pair of the starting timestamp of the clock and the position of
+the match; and otherwise restores point and returns nil."
+ (let ((saved-point (point)) heading-bound)
+ (save-match-data
+ (if org-log-states-order-reversed
+
(org-skip-over-state-notes)
+
(save-excursion
+
(org-back-to-heading t)
+
(beginning-of-line 2)
+
(setq heading-bound (point)))
+
(re-search-backward (concat "^[ \t]*" org-clock-string) heading-bound t))
+ (if (looking-at
+
(concat "^[ \t]* " org-clock-string
+
" \\[\\([0-9]\\{4\\}-[0-9]\\{2\\}-[0-9]\\{2\\}"
+
" +\\sw+ +[012][0-9]:[0-5][0-9]\\)\\][ \t]*$"))
+
(cons (match-string 1) (match-beginning 1))
+
(goto-char saved-point)
+
nil))))
+
(defun org-clock-out (&optional fail-quietly)
"Stop the currently running clock.
If there is no running clock, throw an error, unless FAIL-QUIETLY is set."
_______________________________________________
Emacs-orgmode mailing list
Remember: use `Reply All' to send replies to the list.
address@hiddenhttp://lists.gnu.org/mailman/listinfo/emacs-orgmode