emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
* Triggering clock in/out from org state change and progress logging
@ 2014-08-26 11:00 Alexis Roda
  2014-09-01 17:32 ` Alexis Roda
  0 siblings, 1 reply; 2+ messages in thread
From: Alexis Roda @ 2014-08-26 11:00 UTC (permalink / raw)
  To: emacs-orgmode

Hi list,
as part of learning org I'm trying to configure it so that state changes 
trigger clocking in/out tasks.

Why testing workflow is:

#+TODO: TODO(t) STRT(s!) PAUS(p!) WAIT(w!) | DONE(d!) CANC(c!)

What I try to accomplish:

* entering STRT pauses the active task (if any) and clocks-in the 
current task.

* entering PAUS or WAIT clocks-out the current task (if clocking the 
current task).

* entering TODO probably should reset the current task but I don't care 
at that point.


Changing state and clocking in/out works great but logging is weird:

* Tasks

** STRT first task
    - State "STRT"       from "TODO"       [2014-08-26 dt 12:27]
    :20:
    CLOCK: [2014-08-26 dt 12:27]
    :END:
** TODO second task


Now I change "second task" from TODO to STRT:


* Tasks

** PAUS first task
    - State "PAUS"       from "STRT"       [2014-08-26 dt 12:28]
    - State "STRT"       from "TODO"       [2014-08-26 dt 12:27]
    :20:
    CLOCK: [2014-08-26 dt 12:27]--[2014-08-26 dt 12:28] =>  0:01
    :END:
** STRT second task
    :20:
    CLOCK: [2014-08-26 dt 12:28]
    :END:


"first taks" gets paused and "second task" is started and clocking but 
no logging "State 'STRT' from 'TODO' ..." is added to "second task".

Starting a task only logs in the other task.

After 6 hours struggling with that (clocked with org :) ) I can't figure 
why that's happening. Any clue?


Thanks in advance

Here's the code:

(defvar arv/org-todo-entering-state-clocking-actions
   '(("STRT" . start)
     ("PAUS" . stop)
     ("WAIT" . stop)))

(defvar arv/org-todo-state-change-triggers-clocking-enabled t)
(defvar arv/org-todo-paused-state "PAUS")

(defun arv/org-todo--pause-other-task ()
   (when (org-clock-is-active)
     (save-excursion
       (org-clock-goto)
       (org-clock-out)
       (let ((arv/org-todo-state-change-triggers-clocking-enabled nil)) 
; avoid recursion
         (org-todo arv/org-todo-paused-state)))))

(defun arv/org-todo--state-change (from to)
   (when (and arv/org-todo-state-change-triggers-clocking-enabled
              (not (string= from to)))
     (let ((action (cdr (assoc to 
arv/org-todo-entering-state-clocking-actions))))
       (unless (null action)
         (cond
          ((eq action 'start)
           (arv/org-todo--pause-other-task)
           (org-clock-in))
          ((eq action 'stop)
           (let ((org-state "DONE") ; hackish, review
                 (org-clock-out-when-done t))
             (org-clock-out-if-current)))
          (t (user-error "Unknown action.")))))))

(defun arv/org-todo--state-change-trigger (p)
   (let ((type (plist-get p :type))
         (from (plist-get p :from))
         (to   (plist-get p :to)))
     (when (eq type 'todo-state-change)
       (arv/org-todo--state-change from to))))


(add-hook 'org-trigger-hook 'arv/org-todo--state-change-trigger)

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Triggering clock in/out from org state change and progress logging
  2014-08-26 11:00 Triggering clock in/out from org state change and progress logging Alexis Roda
@ 2014-09-01 17:32 ` Alexis Roda
  0 siblings, 0 replies; 2+ messages in thread
From: Alexis Roda @ 2014-09-01 17:32 UTC (permalink / raw)
  To: emacs-orgmode

Hi list,
after struggling a bit with edebug (too many things to learn) I have 
traced what the problem is. For the archives:

State-change logging is deferred until the command finishes and is 
implemented by the function 'org-add-log-setup' adding the function 
'org-add-log-note' to the hook 'post-command-hook'. The details of the 
note are stored in global variables 'org-log-note-xxx'.

That implementation prevents recursive calls to 'org-todo' (that's what 
my code does in order the pause the active task) from logging both the 
paused and the started log messages.

'org-add-log-note' will be called only once since the hook won't accept 
duplicated entries. Anyway, the innermost call to 'org-add-log-setup' 
will overwrite the variables 'org-log-note-xxx' with the details of the 
note being paused.

The outcome is that only the state change for the paused note is being 
logged.


Now that I know what the problem is I only have to figure a workaround. 
Any clue?



Regards

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2014-09-01 17:32 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-26 11:00 Triggering clock in/out from org state change and progress logging Alexis Roda
2014-09-01 17:32 ` Alexis Roda

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).