I've wanted the exact same "I did this yesterday" behavior for a while and never got around to trying to implement it. But now if I can get points for it ....
This behavior seems to be hard-coded into org-todo
. The line in org.el
that sets the CLOSED timestamp is (org-add-planning-info 'closed (org-current-effective-time))
and the LOGBOOK notes are added by org-add-log-setup
, which in turn calls org-effective-current-time
. org-effective-current-time
does what it sounds like and returns the effective time.
The obvious solution is to temporarily change org-effective-current-time
to something that prompts for a date. But then we get prompted for the date multiple times with every call, which is annoying. I don't know a good way to avoid it, but you can just save off the user inputed value and keep that around until the end of the function.
This code seems to work and only prompts once when a state change would be logged.
(defun org-todo-with-date (&optional arg)
(interactive "P")
(cl-letf* ((org-read-date-prefer-future nil)
(my-current-time (org-read-date t t nil "when:" nil nil nil))
((symbol-function #'org-current-effective-time)
#'(lambda () my-current-time)))
(org-todo arg)
))