Commit ddfcbd3e88bc

Vincent Demeester <vincent@sbr.pm>
2019-03-16 12:45:21
setup-org: clocking improvements + new shortcuts
- F12 for org-agenda, F11 to go to clocked-in task - Automatically clock some capture template - Clocking in mark the task as STARTED Signed-off-by: Vincent Demeester <vincent@sbr.pm>
1 parent 69b8028
Changed files (1)
lisp/setup-org.el
@@ -37,7 +37,9 @@
          ("C-c o l" . org-store-link)
          ("C-c o r r" . org-refile)
          ("C-c o r a" . org-agenda-refile)
-         ("C-c o a" . org-agenda))
+         ("C-c o a" . org-agenda)
+         ("<f12>" . org-agenda)
+         ("<f11>" . org-clock-goto))
   :config
   (use-package find-lisp)
   (setq org-modules
@@ -129,6 +131,92 @@
 	       (:name "Perso" :tag "@home"))))
 	   (org-agenda-list))))
 
+  (defun vde/is-project-p ()
+    "Any task with a todo keyword subtask"
+    (save-restriction
+      (widen)
+      (let ((has-subtask)
+            (subtree-end (save-excursion (org-end-of-subtree t)))
+            (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
+        (save-excursion
+          (forward-line 1)
+          (while (and (not has-subtask)
+                      (< (point) subtree-end)
+                      (re-search-forward "^\*+ " subtree-end t))
+            (when (member (org-get-todo-state) org-todo-keywords-1)
+              (setq has-subtask t))))
+        (and is-a-task has-subtask))))
+
+  (defun vde/is-project-subtree-p ()
+    "Any task with a todo keyword that is in a project subtree.
+Callers of this function already widen the buffer view."
+    (let ((task (save-excursion (org-back-to-heading 'invisible-ok)
+                                (point))))
+      (save-excursion
+        (vde/find-project-task)
+        (if (equal (point) task)
+            nil
+          t))))
+
+  (defun vde/find-project-task ()
+    "Move point to the parent (project) task if any"
+    (save-restriction
+      (widen)
+      (let ((parent-task (save-excursion (org-back-to-heading 'invisible-ok) (point))))
+        (while (org-up-heading-safe)
+          (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
+            (setq parent-task (point))))
+        (goto-char parent-task)
+        parent-task)))
+  
+  (defun vde/is-task-p ()
+    "Any task with a todo keyword and no subtask"
+    (save-restriction
+      (widen)
+      (let ((has-subtask)
+            (subtree-end (save-excursion (org-end-of-subtree t)))
+            (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
+        (save-excursion
+          (forward-line 1)
+          (while (and (not has-subtask)
+                      (< (point) subtree-end)
+                      (re-search-forward "^\*+ " subtree-end t))
+            (when (member (org-get-todo-state) org-todo-keywords-1)
+              (setq has-subtask t))))
+        (and is-a-task (not has-subtask)))))
+
+  (defun vde/is-subproject-p ()
+    "Any task which is a subtask of another project"
+    (let ((is-subproject)
+          (is-a-task (member (nth 2 (org-heading-components)) org-todo-keywords-1)))
+      (save-excursion
+        (while (and (not is-subproject) (org-up-heading-safe))
+          (when (member (nth 2 (org-heading-components)) org-todo-keywords-1)
+            (setq is-subproject t))))
+      (and is-a-task is-subproject)))
+
+  (org-clock-persistence-insinuate)
+  ;; Show lot of clocking history so it's easy to pick items off the C-F11 list
+  (setq org-clock-history-length 23)
+  ;; Change tasks to STARTED when clocking in
+  (setq org-clock-in-switch-to-state 'vde/clock-in-to-started)
+  ;; Clock out when moving task to a done state
+  (setq org-clock-out-when-done t)
+  ;; Save the running clock and all clock history when exiting Emacs, load it on startup
+  (setq org-clock-persist t)
+
+  (defun vde/clock-in-to-started (kw)
+    "Switch a task from TODO to STARTED when clocking in.
+Skips capture tasks, projects, and subprojects.
+Switch projects and subprojects from STARTED back to TODO"
+    (when (not (and (boundp 'org-capture-mode) org-capture-mode))
+      (cond
+       ((and (member (org-get-todo-state) (list "TODO"))
+             (vde/is-task-p))
+        "STARTED")
+       ((and (member (org-get-todo-state) (list "STARTED"))
+             (vde/is-project-p))
+        "TODO"))))
 
   (defvar org-capture-templates (list))
   (setq org-protocol-default-template-key "l")
@@ -163,7 +251,7 @@
                `("j" "Journal entry" entry
                  (file+datetree ,org-default-journal-file)
                  "* %^{title}\n%U\n%?\n%i\nFrom: %a"
-                 :empty-lines 1))
+                 :empty-lines 1 :clock-in t :clock-resume t))
   (add-to-list 'org-capture-templates
                `("w" "Worklog (journal) entry" entry
                  (file+datetree ,org-default-journal-file)
@@ -190,7 +278,8 @@
   - *what works, what doesn't ?*
   - *is there task / stuck projects ?*
   - *enhancement possible ?*
-- [ ] export previous agenda (somewhere)"))
+- [ ] export previous agenda (somewhere)"
+                 :clock-in t :clock-resume t))
 
   ;; Olds, most likely to remove
   (add-to-list 'org-capture-templates