Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I mark Org habits as done in the past

Tags:

org-mode

I regularly mark habits as DONE the day after the activity was done. The habits module automatically updates a bunch of dates in the metadata when I do this, but the date is always today. So then, I have to manually edit the SCHEDULED, LOGBOOK, and LAST_REPEAT states.

Is there a way to mark a habit as DONE for a day in the past? So instead of doing C-c C-t d (I have "d" set up as "DONE") I could get a prompt which asked me for a date.

like image 981
Naomi Slater Avatar asked Aug 21 '14 22:08

Naomi Slater


1 Answers

I've wanted to do this for some time, too, and your question inspired me to finally figure it out.

There is a function called "org-todo-yesterday." By default, it's not mapped to any keys, but you could always call it with M-x org-todo-yesterday (or map it if you're using it a lot). For me, it breaks because it calls "third" which isn't a defined function in my install.

For a more generic function that prompts us for the date and marks things as done at that time, we can add this function (inspired by org-todo-yesterday) to our emacs init file. It will act as if you finished things at 23:59 on the target date, which is hopefully good enough.

(defun dk/org-todo-custom-date (&optional arg)
  "Like org-todo-yesterday, but prompt the user for a date. The time
of change will be 23:59 on that day"
  (interactive "P")
  (let* ((hour (nth 2 (decode-time
                       (org-current-time))))
         (daysback (- (date-to-day (current-time-string)) (org-time-string-to-absolute (org-read-date))))
         (org-extend-today-until (+ 1 (* 24 (- daysback 1)) hour))
         (org-use-effective-time t)) ; use the adjusted timestamp for logging
    (if (eq major-mode 'org-agenda-mode)
      (org-agenda-todo arg)
      (org-todo arg))))
like image 129
Daniel Kessler Avatar answered Oct 07 '22 09:10

Daniel Kessler