0

Using some org-mode utility functions, it is possible to pretty easily iterate over all headlines in an org-mode buffer, such as this one that deletes all headlines.

(org-map-entries
  (lambda ()
    (when t  ; Or some other condition.
      (delete-region (point) (line-end-position)))))

Is there any similar utility function (i.e., robust method) of deleting the whole section instead?

2 Answers 2

2

You can use the org-element API to figure out where the current section begins and ends:

(defun my/org-delete-subtree ()
  (let* ((ctx (org-element-context))
         (type (org-element-type ctx))
         (beg (org-element-property :begin ctx))
         (end (org-element-property :end ctx)))
    (when (eq type 'headline)
      (kill-region beg end))))

The function is supposed to be called with point before the headline of the subtree, so it is suitable for use with org-map-entries.

The API documentation describes the functions above (and much more), but you will have to familiarize yourself with the parse tree representation, if only to figure out what properties (e.g :begin) to use. And you will have to be very careful: it can act as both a whittling knife of exquisite precision and a chainsaw of awesome power that can do a lot of damage.


Some historical comments: as @orgtre points out in a comment and in the other answer, there is a built-in function org-cut-subtree which already implements this functionality (and more), so there is no need to write your own function as I did above.

The org-cut-subtree function dates from the very beginning of Org mode (it was part of Org mode 3.14 which is before there was even a git repo I believe). The syntax specification of Org mode was almost non-existent at the time and the functions were pretty lenient on what they accepted as legal input: Carsten Dominik, the creator of Org mode, wanted a system in plain text to do what he needed (he is an astronomer and he needed a system to keep track of what he had to do, but also take notes, including equations, which is why LaTeX figures so large in Org mode) and he and others (particularly Bastien Guerry) grew it organically over the years.

Eventually, Nicolas Goaziou took over maintenance of the code and added a parser (named org-element, introduced in 2012 with version 7.9.2 ), and defined a more formal (but still fairly informal) syntax, cleaned up corner cases, declared some things illegal (e.g. there was a time when DEADLINE: and SCHEDULED: timestamps could be anywhere - now, they have to be right after the headline). A lot of this functionality was used in the complete overhaul of the export system that was released with Org mode 8.0 in 2013.

Ever since that time, new functions have been using org-element facilities for parsing, rather than the ad-hoc parsing that org-cut/copy-subtree use, but these functions worked, and still work, well enough that nobody has rewritten them to use the current parser.

A lot of these "historical" functions still live in the single biggest file that Org mode has (which, BTW, used to be the only file that Org mode had when it started), org.el, which accounts for about 15% of the total number of lines (not LOC) in Org mode today.

All this is definitely a tangent, but I enjoyed writing it - I hope you enjoyed reading it!

2
  • There is also the built-in command org-cut-subtree.
    – orgtre
    Feb 2 at 14:27
  • @orgtre: you should make your comment into an answer.
    – NickD
    Feb 2 at 14:36
2

There is the built-in command org-cut-subtree for that.

It optionally takes a prefix argument n for the number of subtrees to cut and just calls (org-copy-subtree n 'cut). If you don't want to delete the whole subtree but just the heading and the content under it up to the first subheading, you can use (org-copy-subtree nil 'cut nil t).

4
  • If run with Elisp code, how does this affect the clipboard?
    – Xaldew
    Feb 2 at 15:39
  • 1
    The cut text is added to the front of the kill ring, just like with kill-region. If you don't want that you can use delete-region.
    – orgtre
    Feb 2 at 15:46
  • 1
    I guess that leads to a bit of problem with org-copy-subtree though? Changing it to use delete-region internally is pretty non-trivial
    – Xaldew
    Feb 2 at 15:55
  • 1
    I added a historical note to my answer: I hope you find it informative!
    – NickD
    Feb 2 at 16:53

Your Answer

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

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