Org: Show only Post subtree headings
— Kaushal ModiHow to define a custom org-global-cycle
-like command that collapses
only the Org subtrees with specific properties.
I start this post by introducing what the Org mode global cycling command does, what kind of subtree folding I actually need, and then share the solution with code snippets.
Org Global Cycle #
Org mode has a built-in org-global-cycle
command that you might be
familiar with. It’s bound by default to the S-TAB
key. Each time
this command is called, the Org buffer will cycle through these
states:
- Overview: Show only the Level 1 headings and collapse everything underneath.
- Contents: Show only the Org headings and collapse all the content.
- Show All: Expand all the headings and show their contents too.
If a numeric prefix N is used with this command, it will show only
the Org headings up to Level N. For example, C-2 S-TAB
will show
only the headings up to Level 2.
This is a really helpful command, but I needed something different ..
Skeleton of only Post headings #
I maintain most of this website’s content in a single Org file. I have dozens of blog posts organized in Org subtrees, which I further organize under “category” headings .. It kind of looks like the below mock-up: It’s amazing how many features PlantUML has. If you are interested in creating diagrams like these, check out the PlantUML Salt syntax.
As we can see,
- All the post subtrees are not at Level 1 headings.
- They are also not at a fixed Level N.
- The heading level of the post depends on how many parent categories that post has (and that will also change over time).
I needed to basically show everything leading up to a post subtree heading, and then collapse all the content under that post; even the sub-headings.
The “Collapse All Posts” function #
The modi/org-hugo-collapse-all-posts
function defined below meets
the above requirement:
- It first widens the whole buffer and expands all the headings.
- Then it loops through all the headings and collapses all the post
subtrees i.e. all the subtrees that have the
EXPORT_FILE_NAME
property set. This is where I use theorg-map-entries
magic. - Finally it looks for Org headings that begin with “Footnotes” or “COMMENT” and collapses them as well.
I am using the development version of Org mode (version 9.6, yet to be
released as of org-fold
library. This library obsoletes the use of outline.el
library and
other code-folding related functions in Org mode. So cl-flet
is
used to create function symbol aliases that use the org-fold-*
functions if available, otherwise they fall back to the legacy
functions.
|
|
Binding with C-u C-c TAB
#
The function is ready, but let’s now add a bit of convenience to it.
If a point is under a subtree, C-c TAB
will collapse that subtree
while showing only Level 1 headings, and if a numeric prefix is used,
it will show only those many levels of headings. I decided to bind the
above function to C-u C-c TAB
because,
- The behavior of
modi/org-hugo-collapse-all-posts
falls in the same category as that ofC-c TAB
. - The
C-u C-c ..
binding rolls off the fingers pretty nicely 😃.
This binding is achieved using one of my favorite Emacs features
.. the advice system. The :before-until
Advice Combinator is used
here, which means that if the advising function (below) returns a
nil, the advised or the original function org-ctrl-c-tab
is not
called.
The advising function below detects if the C-u
prefix argument is
used. If it is, the modi/org-hugo-collapse-all-posts
function is
called, otherwise the original org-ctrl-c-tab
function is called.
|
|
Result #
After evaluating the above two snippets, when I do C-u C-c TAB
in
my “blog posts” Org buffer, I see this:
It matches that earlier mockup — Mission accomplished! 💯