3

Sometimes I fall behind in my org-agenda maintenance and have to go back a few days to mark completed tasks. In 90% of cases, I want to mark the task as completed on the day it was due, but org-agenda-todo always uses the current day and time.

What is the easiest way to mark agenda items as completed on the day currently being viewed in the agenda window?

Update: I attempted to adapt the answer to the linked question; ignoring the ugliness of my code, the date seems to be obtained, but org-agenda-todo ignores org-current-effective-time:

(defun org-agenda-todo-view-date (&optional arg)
  (interactive "P")
  (cl-letf* ((org-read-date-prefer-future nil)
             (my-current-time (org-read-date nil t (mapconcat 'number-to-string (append (last (calendar-gregorian-from-absolute org-starting-day)) (butlast (calendar-gregorian-from-absolute org-starting-day))) "-")))
             ((symbol-function #'org-current-effective-time)
              #'(lambda () my-current-time)))
    (org-agenda-todo arg)))
holocronweaver
  • 1,319
  • 10
  • 22
  • Possible duplicate of [How to make org prompt for a timestamp, when changing state of a TODO?](http://emacs.stackexchange.com/questions/9433/how-to-make-org-prompt-for-a-timestamp-when-changing-state-of-a-todo) – erikstokes Nov 25 '16 at 00:41
  • 1
    Similar, but not duplicate. Edited to clarify. Linked question wishes to be prompted for a completion date, but I want the current agenda view day to be used. It should be fully automated, no manual input required beyond pressing `t` to complete the task. – holocronweaver Nov 25 '16 at 06:11

1 Answers1

3

This is similar to another question where the goal was to prompt for the date. Here you just want to use the date under the cursor. We can basically use the same answer, but we get the date in a different way. Instead of prompting with org-read-date, we use org-get-cursor-date. With this the CLOSED property and any logbook entries will be made on whatever date in the agenda you happen to be on when you call org-agenda-todo-view-date.

(require 'cl-lib)

(defun org-agenda-todo-view-date (&optional arg)
  (interactive "P")
  (let ((my-current-time (org-get-cursor-date)))
    (cl-letf* (((symbol-function #'org-current-effective-time)
                (lambda () my-current-time))
               ((symbol-function #'org-today)
                (lambda () (time-to-days (org-current-effective-time)))))
      (let ((current-prefix-arg arg))
        (call-interactively 'org-agenda-todo)))))

Note that the function responsible for updating schedules, org-auto-repeat-maybe, uses org-today to get the date instead of org-current-effective-time (which org-today apparently does not call) so we modify it as well to match.

erikstokes
  • 12,686
  • 2
  • 34
  • 56
  • Wow, that is much simpler way to get the date. =) One problem remains. As is, it moves the due date to the day after today, rather than the day after the day in the agenda view. Any idea how to rectify this? – holocronweaver Nov 25 '16 at 23:42
  • The scheduling function seems to get the date from `org-today` instead of `org-current-effective-time`. We'll have to modify that function as well. – erikstokes Nov 26 '16 at 16:55
  • Yes! That seems to work as intended. Thank you very much for your help. Learned a bit about org internals to boot. – holocronweaver Nov 27 '16 at 08:50