From mboxrd@z Thu Jan 1 00:00:00 1970 From: Alexis Roda Subject: Triggering clock in/out from org state change and progress logging Date: Tue, 26 Aug 2014 13:00:46 +0200 Message-ID: <53FC68DE.3000500@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:43707) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XMEUl-00027T-QO for emacs-orgmode@gnu.org; Tue, 26 Aug 2014 07:01:08 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1XMEUc-0007Po-LB for emacs-orgmode@gnu.org; Tue, 26 Aug 2014 07:00:59 -0400 Received: from mail-we0-x22e.google.com ([2a00:1450:400c:c03::22e]:58173) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1XMEUc-0007Pe-Co for emacs-orgmode@gnu.org; Tue, 26 Aug 2014 07:00:50 -0400 Received: by mail-we0-f174.google.com with SMTP id x48so14460549wes.5 for ; Tue, 26 Aug 2014 04:00:48 -0700 (PDT) Received: from [192.168.1.10] (206.Red-81-39-198.dynamicIP.rima-tde.net. [81.39.198.206]) by mx.google.com with ESMTPSA id pk9sm7396425wjb.16.2014.08.26.04.00.47 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 26 Aug 2014 04:00:48 -0700 (PDT) List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: emacs-orgmode@gnu.org 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)