Commits

Paul Sexton committed 0f7e203

Add variable 'org-gamify-active-p'. When it is set to nil, org-gamify
is prevented from reacting to todo state changes.
Add interactive command 'org-gamify-undo-deltas'. Applies (-1 X DELTA) for
all applicable currency deltas for the task at point.

  • Participants
  • Parent commits dd204cb

Comments (0)

Files changed (1)

File org-gamify.el

   "Day when the cache of deltas was last updated.")
 
 
+(defvar org-gamify-active-p t
+  "If this variable is set to nil, changes in the todo state of a task will not
+trigger currency changes.")
+
+
 ;;; * Variables that can be used to customise behaviour
 
 
     (second (assoc currency deltas))))
 
 
-(defun org-gamify-apply-deltas (task-plist)
+(defun org-gamify-apply-deltas (task-plist &optional invert)
   "Apply the currency deltas for the task at point. This function is called
-when a task is marked 'done'."
+when a task is marked 'done'.
+If 'invert' is non-nil, the deltas are all multiplied by -1 before being
+applied."
   ;; We must check that the new state is a 'done' state, because when repeating
   ;; items are marked done, they immediately revert to 'todo', creating a total
   ;; of 2 state changes. We must only apply deltas ONCE for repeating items.
-  (let ((to-state (plist-get task-plist :to))
-        (from-state (plist-get task-plist :from)))
-    (when (and (member from-state (cons 'todo org-not-done-keywords))
-               (member to-state (cons 'done org-done-keywords)))
-      (let ((deltas (org-gamify-get-deltas))
-            (id (org-id-get (point) t)))
-        (dolist (entry deltas)
-          (destructuring-bind (currency delta) entry
-            (org-gamify-alter-currency currency delta)))
-        (remhash id org-gamify-delta-cache)
-        deltas))))
+  (when org-gamify-active-p
+    (let ((to-state (plist-get task-plist :to))
+          (from-state (plist-get task-plist :from)))
+      (when (and (member from-state (cons 'todo org-not-done-keywords))
+                 (member to-state (cons 'done org-done-keywords)))
+        (let ((deltas (org-gamify-get-deltas))
+              (id (org-id-get (point) t)))
+          (dolist (entry deltas)
+            (destructuring-bind (currency delta) entry
+              (org-gamify-alter-currency currency (if invert (- delta) delta))))
+          (remhash id org-gamify-delta-cache)
+          deltas)))))
 
 
 (add-hook 'org-trigger-hook 'org-gamify-apply-deltas)
         (to-state (plist-get task-plist :to))
         (from-state (plist-get task-plist :from)))
     (cond
-     ((or (not (member from-state (cons 'todo org-not-done-keywords)))
+     ((or (not org-gamify-active-p)
+          (not (member from-state (cons 'todo org-not-done-keywords)))
           (not (member to-state (cons 'done org-done-keywords))))
       t)                                ; return t to avoid blocking
      (t
          (last-updated (or org-gamify-last-update-day
                            (1- now)))
          (update-cycles-due (- now last-updated)))
-    (message "Org-gamify: running daily update of all active tasks...")
-    (when (plusp update-cycles-due)
-      (org-map-entries
-       (lambda ()
-         (loop for day from (- now update-cycles-due) to now
-               do
-               (progn
-                 (let ((scheduled (org-gamify-get-scheduled-day))
-                       (deadline (org-gamify-get-deadline-day))
-                       (today (time-to-days (current-time))))
-                   (run-hook-with-args-until-success
-                    'org-gamify-daily-update-functions
-                    (if scheduled (- today scheduled) nil)
-                    (if deadline (- today deadline) nil)
-                    (org-gamify-habit-chain-length))))))
-       "/!"                            ; this search matches all non-done tasks
-       'agenda 'archive)
-      (setq org-gamify-last-update-day now))))
+    (when org-gamify-active-p
+      (message "Org-gamify: running daily update of all active tasks...")
+      (when (plusp update-cycles-due)
+        (org-map-entries
+         (lambda ()
+           (loop for day from (- now update-cycles-due) to now
+                 do
+                 (progn
+                   (let ((scheduled (org-gamify-get-scheduled-day))
+                         (deadline (org-gamify-get-deadline-day))
+                         (today (time-to-days (current-time))))
+                     (run-hook-with-args-until-success
+                      'org-gamify-daily-update-functions
+                      (if scheduled (- today scheduled) nil)
+                      (if deadline (- today deadline) nil)
+                      (org-gamify-habit-chain-length))))))
+         "/!"                          ; this search matches all non-done tasks
+         'agenda 'archive)
+        (setq org-gamify-last-update-day now)))))
 
 
 (run-at-time "00:00" nil 'org-gamify-daily-update)
     (display-buffer buf)))
 
 
+;;; ** Attempt to 'undo' currency changes
+
+
+(defun org-gamify-undo-deltas ()
+  "Apply the currency deltas for the task at point, multiplied by -1.
+This command is intended for use if the user accidentally applies a currency
+change incorrectly."
+  (interactive)
+  (org-gamify-apply-deltas '(:from todo :to done) t))
+
+
 (provide 'org-gamify)