3

How can I make all done (e.g. DONE) org-mode items "invisible"? I'm using org-mode's "visibility" terminology here, but what I'm referring to is collapsing (folding) those items closed, not making them literally invisible. I don't want to use org's sparse trees for this.

I have multiple custom done states (including SKIP, for example). I want items to be collapsed if they are in any of those states.

1

You can archive all items you want folded.

Archived items (i.e. items marked with the ARCHIVE tag) will always remain folded unless explicitly unfolded via org-force-cycle-archived (C-TAB).

If you want to do a bulk archiving on all DONE items, there is an example here on how to proceed. Something like the following (untested):

(org-map-entries
  '(org-toggle-tag "ARCHIVE" 'on )
  "/+DONE" 'file 'archive 'comment)

This adds the ARCHIVE tag to all headings in the file having the DONE state (excluding commented and archived trees).

  • Thanks, interesting, though not exactly what I'm looking for: I think I just want to set the folded state as a one-off operation rather than changing the text of the buffer like this. I think I'll use archiving in some other cases, though, so good to know about it. – Croad Langshan Apr 30 '16 at 11:08
1

The following command, minimally tested, will hide/fold all entries marked with one of the DONE keywords:

(defun org-fold-all-done-entries ()
  "Close/fold all entries marked DONE."
  (interactive)
  (save-excursion
    (goto-char (point-max))
    (while (outline-previous-heading)
      (when (org-entry-is-done-p)
        (hide-entry)))))

Note that the outline commands may be changing prefixes. If so, you may wish to change the hide-entry line to outline-hide-entry.

  • (hide-entry) doesn't hide the item for me, but (hide-subtree) does. I would edit the answer but I don't understand what you mean by "changing prefixes"? Also, in emacs 25 I don't have an outline-hide-entry (nor any functions whose names start with "outline-hide") – Croad Langshan Apr 30 '16 at 11:15
0

This seems to work for me:

(defun my/org-get-folded-state ()
    (cond
        ((not (or (org-at-item-p) (org-at-heading-p)))
            'not-at-node)
        ((org-before-first-heading-p)
            'not-at-node)
        (t
            (let (eoh eol eos has-children children-skipped struct)
                ;; First, determine end of headline (EOH), end of subtree or item
                ;; (EOS), and if item or heading has children (HAS-CHILDREN).
                (save-excursion
                    (if (org-at-item-p)
                        (progn
                            (beginning-of-line)
                            (setq struct (org-list-struct))
                            (setq eoh (point-at-eol))
                            (setq eos (org-list-get-item-end-before-blank (point) struct))
                            (setq has-children (org-list-has-child-p (point) struct)))
                        (org-back-to-heading)
                        (setq eoh (save-excursion (outline-end-of-heading) (point)))
                        (setq eos (save-excursion (org-end-of-subtree t t)
                                      (when (bolp) (backward-char)) (point)))
                        (setq has-children
                            (or (save-excursion
                                    (let ((level (funcall outline-level)))
                                        (outline-next-heading)
                                        (and (org-at-heading-p t)
                                            (> (funcall outline-level) level))))
                                (save-excursion
                                    (org-list-search-forward (org-item-beginning-re) eos t)))))
                    ;; Determine end invisible part of buffer (EOL)
                    (beginning-of-line 2)
                    (while (and (not (eobp)) ;; this is like `next-line'
                               (get-char-property (1- (point)) 'invisible))
                        (goto-char (next-single-char-property-change (point) 'invisible))
                        (and (eolp) (beginning-of-line 2)))
                    (setq eol (point)))
                (cond
                    ((= eos eoh)
                        'empty-node)
                    ((or (>= eol eos)
                         (not (string-match "\\S-" (buffer-substring eol eos))))
                        'folded)
                    (t
                        'not-folded))))))

(defun my/org-tree-can-fold-p ()
    (not (member (my/org-get-folded-state) (list 'folded 'empty-node))))

(defun my/org-cycle-until-folded ()
    (while (my/org-tree-can-fold-p)
        (org-cycle)))

(defun my/org-hide-done-entries-in-range (start end)
    (save-excursion
        (goto-char end)
        (while (and (outline-previous-heading) (> (point) start))
            (when (org-entry-is-done-p)
                (my/org-cycle-until-folded)))))

(defun my/org-hide-done-entries-in-region (start end)
    (interactive "r")
    (my/org-hide-done-entries-in-range start end))

(defun my/org-hide-done-entries-in-buffer ()
    (interactive)
    (my/org-hide-done-entries-in-range (point-min) (point-max)))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.