Improve feedback when completing repeated tasks from agenda view.

When marking a repeated entry DONE in the daily or weekly agenda, that
task would previously still be shown as TODO, because the repeater
immediately restores the TODO state after moving the time stamp.  This
is bad feedback.

This problem was hard to fix.  Because the same line may be present in
other lines in the same weekly agenda, we cannot simply update all
lines related to this entry.

What we do now is this:  Before the repeater does its work in shifting
the time stamp and resetting the TODO keyword, we take a snapshot of
the headline as it looks then.  And then, when we update the agenda
view, we change only the line at the cursor instead of all lines
related to this entry.  We also make sure that this is only so if the
cursor is in a daily/weekly agenda, on TODAY's date.

There still remain possible inconsistencies.  For example, if you have
a daily repeating task in the weekly agenda, and you move the cursor a
few days into the future and mark it DONE there, the entry will
actually be marked DONE for today, but still show up in today's task
list as TODO.  refreshing the agenda will fix the display in such an
unlikely case.

Thanks to Jack ??? for noticing and reporting this issue.
This commit is contained in:
Carsten Dominik 2008-11-03 08:36:30 +01:00
parent cb1bbaf244
commit 0bbf3a9bd6
3 changed files with 32 additions and 5 deletions

View File

@ -1,3 +1,13 @@
2008-11-03 Carsten Dominik <dominik@science.uva.nl>
* org-agenda.el (org-agenda-todo): Update only the current
headline if this is a repeated TODO, marked done for today.
(org-agenda-change-all-lines): New argument JUST-THIS, to change
only the current line.
* org.el (org-todo): Take a snapshot of the headline if the
repeater might change it.
2008-11-02 Carsten Dominik <dominik@science.uva.nl>
* org-publish.el (org-publish-find-title): Remove buffers visited

View File

@ -4927,8 +4927,10 @@ the same tree node, and the headline of the tree node in the Org-mode file."
(buffer (marker-buffer marker))
(pos (marker-position marker))
(hdmarker (get-text-property (point) 'org-hd-marker))
(todayp (equal (get-text-property (point) 'day)
(time-to-days (current-time))))
(inhibit-read-only t)
newhead)
org-agenda-headline-snapshot-before-repeat newhead just-one)
(org-with-remote-undo buffer
(with-current-buffer buffer
(widen)
@ -4940,12 +4942,19 @@ the same tree node, and the headline of the tree node in the Org-mode file."
(org-todo arg)
(and (bolp) (forward-char 1))
(setq newhead (org-get-heading))
(when (and (org-bound-and-true-p
org-agenda-headline-snapshot-before-repeat)
(not (equal org-agenda-headline-snapshot-before-repeat
newhead))
todayp)
(setq newhead org-agenda-headline-snapshot-before-repeat
just-one t))
(save-excursion
(org-back-to-heading)
(move-marker org-last-heading-marker (point))))
(beginning-of-line 1)
(save-excursion
(org-agenda-change-all-lines newhead hdmarker 'fixface))
(org-agenda-change-all-lines newhead hdmarker 'fixface just-one))
(org-move-to-column col))))
(defun org-agenda-add-note (&optional arg)
@ -4967,7 +4976,7 @@ the same tree node, and the headline of the tree node in the Org-mode file."
(org-flag-heading nil))) ; show the next heading
(org-add-note))))
(defun org-agenda-change-all-lines (newhead hdmarker &optional fixface)
(defun org-agenda-change-all-lines (newhead hdmarker &optional fixface just-this)
"Change all lines in the agenda buffer which match HDMARKER.
The new content of the line will be NEWHEAD (as modified by
`org-format-agenda-item'). HDMARKER is checked with
@ -4975,6 +4984,7 @@ The new content of the line will be NEWHEAD (as modified by
If FIXFACE is non-nil, the face of each item is modified acording to
the new TODO state."
(let* ((inhibit-read-only t)
(line (org-current-line))
props m pl undone-face done-face finish new dotime cat tags)
(save-excursion
(goto-char (point-max))
@ -4982,6 +4992,7 @@ the new TODO state."
(while (not finish)
(setq finish (bobp))
(when (and (setq m (get-text-property (point) 'org-hd-marker))
(or (not just-this) (= (org-current-line) line))
(equal m hdmarker))
(setq props (text-properties-at (point))
dotime (get-text-property (point) 'dotime)

View File

@ -7794,7 +7794,7 @@ TODO state changes
:from previous state (keyword as a string), or nil
:to new state (keyword as a string), or nil")
(defvar org-agenda-headline-snapshot-before-repeat)
(defun org-todo (&optional arg)
"Change the TODO state of an item.
The state of an item is given by a keyword at the start of the heading,
@ -7962,7 +7962,13 @@ For calling through lisp, arg is also interpreted in the following way:
(setq head (org-get-todo-sequence-head state)))
(put-text-property (point-at-bol) (point-at-eol) 'org-todo-head head)
;; Do we need to trigger a repeat?
(when now-done-p (org-auto-repeat-maybe state))
(when now-done-p
(when (boundp org-agenda-headline-snapshot-before-repeat)
;; This is for the agenda, take a snapshot of the headline.
(save-match-data
(setq org-agenda-headline-snapshot-before-repeat
(org-get-heading))))
(org-auto-repeat-maybe state))
;; Fixup cursor location if close to the keyword
(if (and (outline-on-heading-p)
(not (bolp))