Re: [O] Triggering clock in/out from org state change and progress logging

2014-09-01 Thread Alexis Roda

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




[O] Triggering clock in/out from org state change and progress logging

2014-08-26 Thread Alexis Roda

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)