Completely hide the :PROPERTIES: drawer in org-mode
Asked Answered
L

4

31

Could someone please give me some assistance to completely hide the :PROPERTIES: drawer, including the line that says :PROPERTIES:.

* TASKS (with deadines)

    ** Next Action [#A] Ask the geniuses how to do this.  :lawlist:
       DEADLINE: <2013-07-04 Thu >
         :PROPERTIES:
         :ToodledoID: 330686790
         :ToodledoFolder: TASKS
         :Hash:     afa88f17317bbe2ce0ce661333cdcfb4
         :END:
       This line is for notes, which appears underneath the properties drawer.

* UNDATED (without deadlines)

    ** Someday [#A] Close but no cigar -- keep trying.  :lawlist:
          :PROPERTIES:
          :ToodledoID: 330686680
          :ToodledoFolder: TASKS
          :Hash:     eb0b8d360b5b1453dd66ed0c5698e135
          :END:
       This line is for notes, which appears underneath the properties drawer.

I didn't see this feature by Googling, so I'm guessing that some special lines of code will be needed to make this feature request a reality. [In other words, I don't think it is a Super User question because this will need to be invented with some special code.]

Longdrawn answered 4/7, 2013 at 21:24 Comment(0)
L
34

The following answer completely hides everything from :PROPERTIES: through :END:. It can be tested by evaluating (org-cycle-hide-drawers 'children), or (org-cycle-hide-drawers 'all), or in conjunction with the other functions relating to cycling the outline views. The standard functions to unfold that are included within the org-mode family all work -- e.g., show-all; org-show-subtree; etc.

(require 'org)

(defun org-cycle-hide-drawers (state)
  "Re-hide all drawers after a visibility state change."
  (when (and (derived-mode-p 'org-mode)
             (not (memq state '(overview folded contents))))
    (save-excursion
      (let* ((globalp (memq state '(contents all)))
             (beg (if globalp
                    (point-min)
                    (point)))
             (end (if globalp
                    (point-max)
                    (if (eq state 'children)
                      (save-excursion
                        (outline-next-heading)
                        (point))
                      (org-end-of-subtree t)))))
        (goto-char beg)
        (while (re-search-forward org-drawer-regexp end t)
          (save-excursion
            (beginning-of-line 1)
            (when (looking-at org-drawer-regexp)
              (let* ((start (1- (match-beginning 0)))
                     (limit
                       (save-excursion
                         (outline-next-heading)
                           (point)))
                     (msg (format
                            (concat
                              "org-cycle-hide-drawers:  "
                              "`:END:`"
                              " line missing at position %s")
                            (1+ start))))
                (if (re-search-forward "^[ \t]*:END:" limit t)
                  (outline-flag-region start (point-at-eol) t)
                  (user-error msg))))))))))

For anyone who interested in tab cycling between all of the various views (including revealing what is inside the :PROPERTIES: drawer, there is an easy modification to org-cycle-internal-local by adding an additional condition before (t ;; Default action: hide the subtree. . . .

((eq org-cycle-subtree-status 'subtree)
  (org-show-subtree)
  (org-unlogged-message "ALL")
  (setq org-cycle-subtree-status 'all))

Screenshot -- Drawers Hidden:

https://www.lawlist.com/images/org_mode_properties_a.png


Screenshot -- Drawers Visible:

https://www.lawlist.com/images/org_mode_properties_b.png

Longdrawn answered 4/7, 2013 at 21:24 Comment(15)
Why not send that upstream by the way?Sanders
@Michaël -- That is a good idea -- I just emailed a short description and link to whoever subscribes to the org-mode mailing list.Longdrawn
@Michaël -- FYI: The proposed feature has been rejected by the maintainer of the org-mode package and I do not have the inclination to try and convince him to add this feature because the answer above is sufficient to meet my present needs. ["Thank you for the suggestion. However, I think hiding completely stuff from the user is not great. How would you edit it, or even know there are properties there? You can write ":properties:" instead of ":PROPERTIES:", dim them with an appropriate face…"] I vaguely remember a similar response a few years ago, but could not find the old email.Longdrawn
Quick question in case anyone is still paying attention to this. There's already a function called org-cycle-hide-drawers in org-mode. But from what I can tell it's not the same as the function defined above. Would it make sense to update the answer to use a fresh function name? Or is the intent to replace the built-in function?Czechoslovakia
@Czechoslovakia -- The answer contemplates that the user will replace the old built-in function with the new function in the answer above. By using the same name as the built-in function, the new function effectively takes the place of the old built-in function. Just in case the old built-in function has not yet been loaded/read, the first line of this answer above forces the entire library to load so that the new function can take the place of the old built-in function.Longdrawn
@Longdrawn Thanks! Maybe I missed that detail, but even after reading the answer over again it's not clear where it's stated that the function is replacing a built-in function. My first guess was that this function had been added to org-mode after this answer was posted. For clueless users like myself, it might be a good idea to just point out in the answer that this replaces a built-in function... Thanks for posting the answer in the first place! Super helpful stuff.Czechoslovakia
Thanks for the great feature. Regarding the org-cycle-internal-local code at the end, placing it at the beginning of the cond block instead of near the end, has given me better results. Then, the Tab key cycles between 1)fully folded, 2) text + children, 3) 2 + children text, 4) 3 + drawersPytlik
@Lawlist/ @Harshavardhan: Noob here. Can you please elaborate what needs to be done? Do I just place ((eq org-cycle-subtree-status 'subtree) (org-show-subtree) (org-unlogged-message "ALL") (setq org-cycle-subtree-status 'all)) in my .emacs and I will be done? Or anything more to be done?Gillette
I did C-h f and entered: org-cycle-internal-local. That led me to a page that gave a link to org.el. Upon clicking that I did find the source code for org-cycle-internal-local. Inside that I pasted the modification before (t ;; Default action: hide the subtree. . . . as instructed. Now my code looks like this: (run-hook-with-args 'org-cycle-hook 'subtree))) ;; inserted lines here... (t ;; Default action: hide the subtree. (run-hook-with-args 'org-pre-cycle-hook 'folded) But TAB doesn't show PROPERTIES drawer. Please help!Gillette
@Gillette -- When tinkering, it is always better to leave the original source code "as is". Copy the entire function to a scratch / working buffer, tinker to your heart's content, and evaluate the buffer each time you want to test out a new modification, e.g., M-x eval-buffer. Once you get your function working as desired, then you can copy it over to your .emacs or init.el file. A library like org.el will most likely load before .emacs or init.el, but other libraries may need to be specifically loaded prior to your modified code being evaluated -- you are redefining.Longdrawn
@lawlist: thanks a lot! I should have thought of that!Gillette
@lawlist: Sorry, need more help: When I do M-x I don't see org-cycle-hide-drawers or org-cycle-internal-local. When I do C-h k TAB I see org-cycle. So I am a little confused about what and how to call/ use. These are my ideas: 1. paste everything in *scratch* and write (org-cycle-hide-drawers) or (org-cycle-internal-local) with C-j? But I think for these functions it matters where the point and mark are. So I doubt if above will work. 2. put a keybind in my .emacs for these functions. Then with right point and mark invoke keybinding. Please tell me if anything else?Gillette
@lawlist: @lawlist: one more question - no where in your patch for org-cycle-internal-local: ((eq org-cycle-subtree-status 'subtree) (org-show-subtree) (org-unlogged-message "ALL") (setq org-cycle-subtree-status 'all)) is org-cycle-hide-drawers mentioned. How does your patch actually work?. And how is org-cycle which is bound to TAB related to org-cycle-internal-local? At the end I just want to TAB and cycle through the various folding states. Currently to un-hide the properties drawer I comment out the org-cycle-hide-drawers from my .emacs. Then reload.Gillette
@Gillette -- it sounds like you need more assistance than can be provided in comments to an answer relating to org-cycle-hide-drawers (with a side-comment relating to a modification of org-cycle-internal-local). This answer was written in 2017 (approximately 5 years ago), and it is entirely possible that the code of org-cycle-internal-local has changed during that time period. It may behoove you to launch a new question on emacs.stackexchange.com and you can receive dedicated attention to your particular use-case, taking into consideration a current version of org-mode.Longdrawn
For the anyone following the discussions until here: I am cross linking here a follow up question I launched based on the above discussions! @lawlist: Thanks for your inputs!Gillette
H
5

as of 2023, there's a emacs package org-tidy that helps with this

https://github.com/jxq0/org-tidy

(use-package org-tidy
  :ensure t
  :config
  (add-hook 'org-mode-hook #'org-tidy-mode))
Hip answered 8/12, 2023 at 4:47 Comment(1)
This is very good compare to other solutions thanks for it!!!Almeria
E
-1

That's simply not possible right now, at least not without (a lot of?) extra coding...

Problem is: how would you unhide it? Would you see "..." alone?

Eliciaelicit answered 4/7, 2013 at 22:19 Comment(4)
There must be a simple solution, like re-search-forward with a save excursion from top to bottom of the buffer for every line beginning with :PROPERTIES: through to and including the word :END: and hit the code fold button, so that it folds up underneath the previous line. Then the unfold everything button to display everything, and from there back to cycling.Longdrawn
The icing on the cake would be an upside down triangle at the end of the first line to indicate a code fold. :)Longdrawn
A full-fledged solution now exists -- :)Longdrawn
@american-ninja-warrior -- sorry for the delay in responding. I see that at least one other person had the same inquiry as you (based upon the upvote to your question). The accepted answer in this thread contains a full-fledged solution as far as I am aware -- I have been using that solution since about the year 2013 to the present.Longdrawn
M
-2

This allows you to toggle the properties of the header you're currently in.

(defun org-toggle-properties ()
  ;; toggle visibility of properties in current header if it exists
  (save-excursion
    (when (not (org-at-heading-p))
      (org-previous-visible-heading 1))
    (when (org-header-property-p)
      (let* ((a (re-search-forward "\n\\:" nil t)))
        (if (outline-invisible-p (point))
            (outline-show-entry)
          (org-cycle-hide-drawers 'all))))))
Mulder answered 22/9, 2018 at 8:29 Comment(1)
The call of the question seeks a means to completely hide the :PROPERTIES: drawer -- including the line that says :PROPERTIES:. In addition, the function org-header-property-p does not exist in the most recent version of org-mode available by cloning as of 09/23/2018: git clone https://code.orgmode.org/bzg/org-mode.git. That function does not exist in a few of the prior versions of org-mode that I also grepped. As I am unable to test the function due to missing components, I do not know if there are any other issues. Also, Google cannot find org-header-property-p.Longdrawn

© 2022 - 2025 — McMap. All rights reserved.