Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Emacs org-mode: How can i fold everything but the current headline?

Tags:

emacs

org-mode

I use org-mode to handle my tasks and projects in multiple files.

In the weekly agenda, it is possible to jump to the location of each TODO entry using <TAB> or <RET>. If the target file was not previously open, it is loaded an the cursor is set to the correct headline and the entire document is unfolded, including drawers.

I would very much prefer to see only a sparse tree with everything but the correct headline folded (subtree visibility does not matter).

It is possible to collapse the entire tree by cycling global visibility using C-u <TAB, but then I have to find the heading again.

I know I can hide the rest by narrowing the buffer as described here: Emacs, How can I display only current task and hide others in org-mode? but then I loose context (parent heading, easy access to siblings) and the drawers are still open.

Ideally, I would like to have a command that shows the following:

  • The top level headings
  • The current headline, and all it's parents up to the top level
  • The current headline's children

Edit:

A slighty modified version of the functions user3173715 posted seems to do the trick:

(defun org-show-current-heading-tidily ()
  "Show next entry, keeping other entries closed."
  (if (save-excursion (end-of-line) (outline-invisible-p))
      (progn (org-show-entry) (show-children))
    (outline-back-to-heading)
    (unless (and (bolp) (org-on-heading-p))
      (org-up-heading-safe)
      (hide-subtree)
      (error "Boundary reached"))
    (org-overview)
    (org-reveal t)
    (org-show-entry)
    (show-children)))
like image 819
Patrick B. Avatar asked Aug 06 '14 13:08

Patrick B.


3 Answers

This is based on the answer in the edit in the actual question.

If of help to anyone: When I tried to bind the above to a hotkey, I kept getting an error, commandp wrong argument something something ... It turned out one had to add the (interactive) flag to make it work. Below is an example of the function tied to M-=

(defun org-show-current-heading-tidily ()
  (interactive)  ;Inteactive
  "Show next entry, keeping other entries closed."
  (if (save-excursion (end-of-line) (outline-invisible-p))
      (progn (org-show-entry) (show-children))
    (outline-back-to-heading)
    (unless (and (bolp) (org-on-heading-p))
      (org-up-heading-safe)
      (hide-subtree)
      (error "Boundary reached"))
    (org-overview)
    (org-reveal t)
    (org-show-entry)
    (show-children)))

(global-set-key "\M-=" 'org-show-current-heading-tidily)

@Patrick.B thanks for edit!

like image 106
Leo Ufimtsev Avatar answered Nov 20 '22 03:11

Leo Ufimtsev


I am not very sure if this is your demand (I just think it is suitable for your question title), but I use these two functions with plenty of pleasures by binding them in the speed command of org-mode. You can find these two functions in org-mode hacks. I slightly modified them to meet my purposes.

The two functions support:

  1. Unfold every other headings except current heading
  2. Move current heading to top of screen for wider reading area.

In order to accomplish (2), you need to (setq recenter-positions '(top bottom)), there may be some better solutions, but I did not dig into it.

(defun ded/org-show-next-heading-tidily ()
  "Show next entry, keeping other entries closed."
  (if (save-excursion (end-of-line) (outline-invisible-p))
      (progn (org-show-entry) (show-children))
    (outline-next-heading)
    (unless (and (bolp) (org-on-heading-p))
      (org-up-heading-safe)
      (hide-subtree)
      (error "Boundary reached"))
    (org-overview)
    (org-reveal t)
    (org-show-entry)
    (recenter-top-bottom)
    (show-children)
    (recenter-top-bottom)))

(defun ded/org-show-previous-heading-tidily ()
  "Show previous entry, keeping other entries closed."
  (let ((pos (point)))
    (outline-previous-heading)
    (unless (and (< (point) pos) (bolp) (org-on-heading-p))
      (goto-char pos)
      (hide-subtree)
      (error "Boundary reached"))
    (org-overview)
    (org-reveal t)
    (org-show-entry)
    (recenter-top-bottom)
    (show-children)
    (recenter-top-bottom)))

And you can bind them with org-mode speed key with j and l, then you can use j and l to control the folding of headings when your cursor is in the beginning of headings.

(setq org-speed-commands-user
      '(("j" . ded/org-show-next-heading-tidily)
        ("l" . ded/org-show-previous-heading-tidily))))

It is perfect for reading org-mode files, cheers!

like image 25
Leu_Grady Avatar answered Nov 20 '22 01:11

Leu_Grady


Check your org startup options (customize-group > org-startup) like org-startup-folded or org-agenda-inhibit-startup (others have mentioned these already) and set the options to show only the folded view. Org mode variables like #+STARTUP are discussed here.

You may notice that everything is folded when you now jump to the agenda, even the parents of the active item may not be visible. You can then make the context (parents, children, next sibling) visible with org-reveal (C-c C-r as per the manual)

like image 2
quazgar Avatar answered Nov 20 '22 03:11

quazgar