Hi, I’ve been working on getting org-mode to automatically clock into an item’s ancestor when clocking out of that item. The way I have it set up now, it walks up the tree looking for an item that has a particular property set. If that property is non-nil, it clocks in; if it’s nil, it doesn’t. Either way, it stops looking at that point. Here’s what I have so far:
,----[ Conditionally resuming parent clocks ] | (defconst +aankh/org-resume-parent-clock-property+ "AUTO_RESUME_CLOCK" | "The name of the property that indicates whether a task's clock | should be restarted upon clocking out of its subtasks. When | this is not `nil' according to `org-not-nil', the task's clock | will be restarted.") | | (defun aankh/maybe-resume-parent-clock () | (save-excursion | (loop | until (= (org-current-level) 1) | do (org-up-heading-all 1) | when (member +aankh/org-resume-parent-clock-property+ | (mapcar 'car (org-entry-properties))) | do (let ((resume | (org-entry-get | nil | +aankh/org-resume-parent-clock-property+))) | (when (org-not-nil resume) | (org-clock-in)) | (return resume))))) | | (setq aankh/org-resume-parent-clock-enable t) | | (defun aankh/read-resume-parent-clock-property (&rest rest) | (declare (ignore rest)) | (org-icompleting-read | "Automatically restart this task's clock when clocking out of a subtask? " | '("t" "nil"))) | | (when aankh/org-resume-parent-clock-enable | (add-hook 'org-clock-out-hook 'aankh/maybe-resume-parent-clock) | (add-to-list 'org-default-properties | +aankh/org-resume-parent-clock-property+) | (add-to-list 'org-property-set-functions-alist | `(,+aankh/org-resume-parent-clock-property+ | . aankh/read-resume-parent-clock-property))) `---- So given this structure: ,----[ example.org ] | * Foo | | * Bar | :PROPERTIES: | :AUTO_RESUME_CLOCK: t | :END: | | *** Quux | :PROPERTIES: | :AUTO_RESUME_CLOCK: t | :END: | | ***** Frob | | * Baz `---- When I clock out of ‘Frob’, I’m automatically clocked into ‘Quux’, and when I clock out of ‘Quux’, I’m automatically clocked into ‘Bar’. This works pretty well, except for one problem: it happens *every time* I clock out, meaning that if I’m clocked into ‘Quux’ and I then hit C-c C-x C-i on ‘Frob’, I end up being clocked into both ‘Bar’ and ‘Frob’, because I’m automatically clocked out of ‘Quux’; my code is run, clocking me into ‘Bar’; and then the normal clocking mechanism clocks me into ‘Frob’ (at least, I *think* the hook runs first). I guess what I’m wondering is, what’s a good way to avoid this double-clocking? And while I’m asking for help, can anyone think of some less obnoxious names for the functions, variables and property? :-) I hope all this makes sense. Thanks for your time. Aankhen