0

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"

1
  • 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, 2019 at 17:28

1 Answer 1

1

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)
  (interactive)
  (setq +org-hide-all-except-headlines-and-drawers
        (not +org-hide-all-except-headlines-and-drawers))
  (org-element-map (org-element-parse-buffer)
      (cl-remove-if
       (lambda (it) (member it '(headline property-drawer drawer section node-property)))
       org-element-all-elements)
    (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))))))
4
  • 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, 2019 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. Dec 17, 2019 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, 2019 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. Dec 20, 2019 at 11:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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