diff options
author | Bastien <bzg@gnu.org> | 2020-02-14 10:32:35 +0100 |
---|---|---|
committer | Bastien <bzg@gnu.org> | 2020-02-14 10:32:35 +0100 |
commit | 27e4d7ce487b38428618ed1fb2a6e2a1b59098bc (patch) | |
tree | 6460679d7cb066dbcc8a52e36784af2376265b76 | |
parent | 29f44df758d182873c9241f3cb202968b410f0bd (diff) | |
download | org-mode-27e4d7ce487b38428618ed1fb2a6e2a1b59098bc.tar.gz |
Prevent infinite loop when showing new time in agenda
* lisp/org-agenda.el (org-agenda-dim-blocked-tasks): Don't use
an overlay to make the task invisible, use text properties.
(org-agenda--mark-blocked-entry): Add text property
'org-filter-type to later use `org-agenda-filter-hide-line' if
necessary.
(org-agenda-filter-hide-line): Fix docstring.
The related bug was first reported in 2013 by Matt Lundin here:
https://lists.gnu.org/archive/html/emacs-orgmode/2013-08/msg00072.html
Then Andrew Hyatt reported it again, and provided a minimal recipe on
how to reproduce it consistently.
Thanks a lot to both of them.
-rw-r--r-- | lisp/org-agenda.el | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/lisp/org-agenda.el b/lisp/org-agenda.el index aed1b24..ec12710 100644 --- a/lisp/org-agenda.el +++ b/lisp/org-agenda.el @@ -4003,7 +4003,7 @@ dimming them." (when (called-interactively-p 'interactive) (message "Dim or hide blocked tasks...")) (dolist (o (overlays-in (point-min) (point-max))) - (when (eq (overlay-get o 'org-type) 'org-blocked-todo) + (when (eq (overlay-get o 'face) 'org-agenda-dimmed-todo-face) (delete-overlay o))) (save-excursion (let ((inhibit-read-only t)) @@ -4011,22 +4011,26 @@ dimming them." (while (let ((pos (text-property-not-all (point) (point-max) 'org-todo-blocked nil))) (when pos (goto-char pos))) - (let* ((invisible (eq (org-get-at-bol 'org-todo-blocked) 'invisible)) + (let* ((invisible + (eq (org-get-at-bol 'org-todo-blocked) 'invisible)) + (todo-blocked + (eq (org-get-at-bol 'org-filter-type) 'todo-blocked)) (ov (make-overlay (if invisible (line-end-position 0) (line-beginning-position)) (line-end-position)))) - (if invisible - (overlay-put ov 'invisible t) + (when todo-blocked (overlay-put ov 'face 'org-agenda-dimmed-todo-face)) - (overlay-put ov 'org-type 'org-blocked-todo)) - (forward-line)))) + (when invisible + (org-agenda-filter-hide-line 'todo-blocked))) + (move-beginning-of-line 2)))) (when (called-interactively-p 'interactive) (message "Dim or hide blocked tasks...done"))) (defun org-agenda--mark-blocked-entry (entry) - "For ENTRY a string with the text property `org-hd-marker', if -the header at `org-hd-marker' is blocked according to + "If ENTRY is blocked, mark it for fontification or invisibility. + +If the header at `org-hd-marker' is blocked according to `org-entry-blocked-p', then if `org-agenda-dim-blocked-tasks' is 'invisible and the header is not blocked by checkboxes, set the text property `org-todo-blocked' to `invisible', otherwise set it @@ -4050,7 +4054,9 @@ to t." (put-text-property 0 (length entry) 'org-todo-blocked (if really-invisible 'invisible t) - entry))))))) + entry) + (put-text-property + 0 (length entry) 'org-filter-type 'todo-blocked entry))))))) entry) (defvar org-agenda-skip-function nil @@ -8064,13 +8070,13 @@ tags in the FILTER if any of the tags in FILTER are grouptags." org-agenda-filtered-by-top-headline t)) (defun org-agenda-filter-hide-line (type) - "Hide lines with TYPE in the agenda buffer." + "If current line is TYPE, hide it in the agenda buffer." (let* (buffer-invisibility-spec - (b (max (point-min) (1- (point-at-bol)))) - (e (point-at-eol))) + (beg (max (point-min) (1- (point-at-bol)))) + (end (point-at-eol))) (let ((inhibit-read-only t)) (add-text-properties - b e `(invisible org-filtered org-filter-type ,type))))) + beg end `(invisible org-filtered org-filter-type ,type))))) (defun org-agenda-remove-filter (type) (interactive) |