emacs-orgmode
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Orgmode] [PATCH] Auto resume clock-in fails


From: Adam Elliott
Subject: [Orgmode] [PATCH] Auto resume clock-in fails
Date: Thu, 09 Apr 2009 15:55:43 -0400
User-agent: Thunderbird 2.0.0.21 (Windows/20090302)

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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]