Fix bulk agenda processing with parents and children in the loop

Bernt Hansen writes:

> Every so often I run into a situation where bulk refiling
> doesn't work anymore.
>
> I currently have 15 items in my refile.org file that I want
> to refile to other locations.  I marked a few of them and
> bulk refiled them just fine.  Then I marked a few more and B
> r fails with "Cannot find entry for marker #<marker at
> 297156 in norang.org>"
>
> I think this happens when I mark multiple tasks in the same
> subtree (i.e. the parent and a sibling) and refile both to
> the same location.  After that it gets confused.
>
> If I have a task like this in refile.org
>
> #+FILETAGS: REFILE
> * Test
> ** Test 2
>
> and run a tags match on REFILE I see both tasks.  Mark both
> with m in the agenda and B r to some other location.  It
> refiles the first (and this moves the sibling too) and then
> it's broken after that.
>
> I get the following backtrace
>
> Debugger entered--Lisp error: (error "Cannot find entry for
> marker #<marker at 297156 in norang.org>")

Indeed the happens because, when a parent gets refiled or
achieved, any entries corresponding to its children are
removed from the agenda.

We address this issue by

- sorting the markers, to make sure parents will be handled
  before children

- No longer throwing an error when a bulk action entry no
  longer is present in the agenda - most likely it was taken
  care of together with its parent.
This commit is contained in:
Carsten Dominik 2009-08-04 22:34:53 +02:00
parent 064c7976cf
commit babd053bd6
2 changed files with 31 additions and 8 deletions

View File

@ -1,5 +1,10 @@
2009-08-04 Carsten Dominik <carsten.dominik@gmail.com>
* org-agenda.el (org-agenda-bulk-action): Make sure parents are
handled before children, and do not error if an entry is not
found, probably because it hase been remove when the parent was
archived or refiled.
* org.el (org-ido-completing-read): Accept straight lists for
completion as well as alists.

View File

@ -6335,7 +6335,7 @@ This will remove the markers, and the overlays."
(message "Bulk: [r]efile [$]archive [A]rch->sib [t]odo [+/-]tag [s]chedule [d]eadline")
(let* ((action (read-char-exclusive))
(entries (reverse org-agenda-bulk-marked-entries))
cmd rfloc state e tag (cnt 0))
cmd rfloc state e tag (cnt 0) (cntskip 0))
(cond
((equal action ?$)
(setq cmd '(org-agenda-archive)))
@ -6391,17 +6391,35 @@ This will remove the markers, and the overlays."
(fmakunbound 'read-string)))))))
(t (error "Invalid bulk action")))
;; Sort the markers, to make sure that parents are handled before children
(setq entries (sort entries
(lambda (a b)
(cond
((equal (marker-buffer a) (marker-buffer b))
(< (marker-position a) (marker-position b)))
(t
(string< (buffer-name (marker-buffer a))
(buffer-name (marker-buffer b))))))))
;; Now loop over all markers and apply cmd
(while (setq e (pop entries))
(goto-char
(or (text-property-any (point-min) (point-max) 'org-hd-marker e)
(error "Cannot find entry for marker %s" e)))
(eval cmd)
(setq org-agenda-bulk-marked-entries (delete e org-agenda-bulk-marked-entries))
(setq cnt (1+ cnt)))
(setq pos (text-property-any (point-min) (point-max) 'org-hd-marker e))
(if (not pos)
(progn (message "Skipping removed entry at %s" e)
(setq cntskip (1+ cntskip)))
(goto-char pos)
(eval cmd)
(setq org-agenda-bulk-marked-entries
(delete e org-agenda-bulk-marked-entries))
(setq cnt (1+ cnt))))
(setq org-agenda-bulk-marked-entries nil)
(org-agenda-bulk-remove-all-marks)
(message "Acted on %d entries" cnt)))
(message "Acted on %d entries%s"
cnt
(if (= cntskip 0)
""
(format ", skipped %d (disappeared before their turn)"
cntskip)))))
;;; Appointment reminders