Using spacemacs I would like to be able to display an org mode document such that:

  1. all headings are visible
  2. all drawers are open and their contents visible
  3. all other body text is invisible

It would also be acceptable if instead point 2. read "all comments (lines starting # or delimited by #+BEGIN_COMMENT / #+END_COMMENT) are visible"

  • I am still using an out-dated version of org-mode and I have no idea how the latest/greatest version behaves by default (without any user-configuration). That being said, if the behavior you seek cannot be achieved with regular tab cycling, then you will probably need to modify the function org-cycle-internal-local by adding additional conditions. In a thread where I wrote-up how to completely hide the word :PROPERTIES: and drawers, I mention a small snippet used to achieve an additional level of visibility/invisibility when tab-cycling: stackoverflow.com/a/17492723/2112489 – lawlist Dec 15 '19 at 17:28

You can add overlays with the invisible property to everything except headlines and drawers (see overlay properties section of the manual). In the code below I use the org element api to traverse the org file and add overlays with the invisible property to everything except headlines and drawers. I put the relevant code in the function +org/toggle-hide-all-except-headlines-and-drawers (aptly named if a bit verbose) so that you could toggle this because I figure you'll likely want to go back and forth.

One caveat is that when you fold a heading the folding looks scrunched up (there's no separation between headings). But I think this is a separate problem having to do with how org implements overlays. In any case, in my tests everything was hidden except headlines and properties.

(defvar +org-hide-all-except-headlines-and-drawers nil)

(defun +org/toggle-hide-all-except-headlines-and-drawers (&optional reveal)
  (setq +org-hide-all-except-headlines-and-drawers
        (not +org-hide-all-except-headlines-and-drawers))
  (org-element-map (org-element-parse-buffer)
       (lambda (it) (member it '(headline property-drawer drawer section node-property)))
    (lambda (elt)
      (let ((beg (org-element-property :begin elt))
            (end (org-element-property :end elt)))
        (if +org-hide-all-except-headlines-and-drawers
            (overlay-put (make-overlay beg end) 'invisible t)
          (remove-overlays beg end 'invisible t))))))
| improve this answer | |
  • You need to make drawers visible (see point 2) in the THEN form which I think you can do using (org-show-all '(drawers)). You also need (org-flag-drawer t) in the ELSE form to hide the drawers. The other option would be to include comment-block to the list of elements. Good work so far but I think you also need to address point 3. – jagrg Dec 17 '19 at 14:32
  • Ok. I'll add that. Regarding point 3 I thought I had addressed that. After I run the function everything is invisible except property drawers and headlines. – Aquaactress Dec 17 '19 at 15:06
  • By "all other body text" I read make all text invisible except the one in the current entry ;) Perhaps @user2567544 can clarify. – jagrg Dec 18 '19 at 2:03
  • To clarify, I would like to be able to view all headlines with all drawer or comment text, but no other body text. – user2567544 Dec 20 '19 at 11:28

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.