Skip to content

Support for property drawers (revisited) #62

@danielkrizian

Description

@danielkrizian

Revisiting #27 (I don't have permissions to reopen it), which discusses interactive toggling of property drawers not being in the scope of org-appear, I thought perhaps supporting dynamic toggling instead of interactive toggling is aligned with the philosophy of org-appear - i.e. re-appear-ance of any already hidden property drawer when user:

  1. set the drawer(s) to be hidden at startup; and
  2. set org-appear-autodrawers to non-nil and org-hidden-drawers is non-nil; and
  3. has cursor/point near hidden property drawer, i.e. one or customizable number of lines above or below the drawer

Starting from functions that hide the properties drawers:
(copied here since the original is now buried in old version of Hitchhiker's-Rough-Guide-to-Org-roam-V2; slightly modified)

      (add-hook 'org-mode-hook (lambda () (setq-local org-drawers-hidden nil)))

      (defun org-hide-properties ()
        "Hide all org-mode headline property drawers in buffer. Could be slow if it has a lot of overlays."
        (interactive)
        (save-excursion
          (goto-char (point-min))
          (while (re-search-forward
                  "^ *:properties:\n\\( *:.+?:.*\n\\)+ *:end:\n" nil t)
            (let ((ov_this (make-overlay (match-beginning 0) (match-end 0))))
              (overlay-put ov_this 'display "")
              (overlay-put ov_this 'hidden-prop-drawer t))))
        (setq org-drawers-hidden t))

      (defun org-show-properties ()
        "Show all org-mode property drawers hidden by org-hide-properties."
        (interactive)
        (remove-overlays (point-min) (point-max) 'hidden-prop-drawer t)
        (setq org-drawers-hidden nil))

      (defun org-toggle-properties ()
        "Toggle visibility of property drawers."
        (interactive)
        (if org-drawers-hidden
            (org-show-properties)
          (org-hide-properties)))

I have this working prototype:

      (defcustom org-appear-autodrawers t
        "Non-nil enables automatic toggling of hidden property drawers.
      Does not have an effect if `org-drawers-hidden' is nil"
        :type 'boolean
        :group 'org-appear)

      (defvar-local org-appear-unhidden-drawers nil
        "List of currently unhidden property drawers in the buffer.")

      (defun hide-near-point-otherwise-unhide ()
        "Dynamically hide or unhide property drawers based on cursor proximity."
        (let ((unhidden-drawers-near-point
               (cl-loop for pos in '(-1 2)
                        for drawer-near-point = (org-find-overlays 'hidden-prop-drawer (line-beginning-position pos))
                        when drawer-near-point do (overlay-put (car drawer-near-point) 'display nil) ;; unhide drawer near point
                        append drawer-near-point)))
          (dolist (previously-unhidden-drawer org-appear-unhidden-drawers)
              (unless (member previously-unhidden-drawer unhidden-drawers-near-point)
                (overlay-put previously-unhidden-drawer 'display ""))) ;; hide previously unhidden drawer no longer near point
          (setq-local org-appear-unhidden-drawers unhidden-drawers-near-point)))

      (defun org-appear-dynamic-drawers-visibility--setup ()
        "Set up dynamic drawer visibility for Org-mode."
        (add-hook 'post-command-hook #'hide-near-point-otherwise-unhide nil t))

      (defun org-appear-dynamic-drawers-visibility--cleanup ()
        "Remove dynamic drawer visibility for Org-mode."
        (remove-hook 'post-command-hook #'hide-near-point-otherwise-unhide t))

      (add-hook 'org-mode-hook #'org-appear-dynamic-drawers-visibility--setup)
      (add-hook 'org-mode-hook
                (lambda () (add-hook 'kill-buffer-hook #'org-appear-dynamic-drawers-visibility--cleanup nil t)))

Of course it would be better to implement with org-elements rather than re-search-forward.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions