(current as of org 8.2.10)

I have a thing (shameless plug) that outputs a simple snippet of org-headings in a single file that look like this:

* little boys
  - snakes
  - snails
  - puppy dog tails
* little girls
  - sugar
  - spice
  - everything nice
** addendum
  - etc.

These are meant to go into another file through org-insert functions, specifically, a subheading of that other file.

In order to do that I have to demote all of the headings so that they slide nicely into place. How can I do that?

I tried:

  • C-x r t to prepend asterisks; this adds asterisks to every line
  • C-x h M-S-<right> to try demoting the whole selection; this only demoted the first line

Further issue: org-metaright does not demote subtrees

Commenters were correct that C-x h M-<right> (org-metaright) promotes or demotes visible selections. However, this ignores their subtrees, resulting in reordering of their substructure. The same behavior occurs with org-do-demote called on a selection.

  • 4
    What command does M-S-<right> run? For me (Emacs 24.3.1, Org 8.2.10), M-<right> runs org-metaright, and that does the proper behavior (that is, adds a single asterisk to the "little boys" and "little girls" lines). Similarly, C-x h M-x org-do-demote also works properly.
    – zck
    Commented Dec 25, 2014 at 2:51
  • 4
    I might not be understanding the question, but doesn't org-metaright operate on a selected region?
    – Dan
    Commented Dec 25, 2014 at 2:51
  • 3
    Demoting and promoting works with selected regions, if that might be of use in this situation.
    – lawlist
    Commented Dec 25, 2014 at 7:19
  • I cannot find org-insert-file as a standard orgmode command.
    – Juancho
    Commented Dec 26, 2014 at 15:19
  • 2
    @TrevorAlexander Can't you just call show-all before org-do-demote?
    – Malabarba
    Commented Dec 30, 2014 at 22:20

5 Answers 5


Org headlines are simply lines starting with a *. So you can cycle through all of them and manually insert an * on each one to get the effect you want.

(defun endless/demote-everything (number beg end)
  "Add a NUMBER of * to all headlines between BEG and END.
Interactively, NUMBER is the prefix argument and BEG and END are
the region boundaries."
  (interactive "p\nr")
        (narrow-to-region beg end)
        (goto-char (point-min))
        (let ((string (make-string number ?*)))
          (while (search-forward-regexp "^\\*" nil t)
            (insert string)))))))

At first you might be worried this would catch undesired edge cases, such as a #+SRC_BLOCK where one of the lines starts with a *. But org-mode itself uses this method to identify headlines, so no org buffer should ever contain a * as the first char of a line unless it's a headline.

  • I think it is more usual for functions to act on the (possibly narrowed) buffer when there is no region. Also why use of save-match-data in this specific function ? Most other functions/commands do not preserve the match data anyway. Lastly, in fact org uses "^\*+ " (aka org-outline-regexp-bol), i.e. there must be a space after the stars.
    – YoungFrog
    Commented Feb 20, 2015 at 16:23
  • It's not necessary to manually search for the org-mode headlines. There is an API for this and you can use the function org-map-tree like in this example from the Emacs wiki: orgmode.org/worg/org-hacks.html#orgheadline9 Commented Nov 18, 2015 at 23:56

If I understand it correctly, you have a list of subtrees

* A
** A1
*** A1a
* B
** B1

and want to insert them into another subtree

* First
** First Sub
* Second

at the right level:

* First
** First Sub
*** A
**** A1
***** A1a
*** B
**** B1
* Second

As this is Emacs (and org-mode of course), there is a function for this ;-)

Just use org-paste-subtree like so:

  1. save your new list in the kill ring (select and M-w)
  2. enter *** after First Sub
  3. call org-paste-subtree

The function is described as

Paste the clipboard as a subtree, with modification of headline level.

and will work for demoting and promoting the subtree in the kill ring.

org-mode can even be configured to use this style of yank every time a subtree is yanked into a subtree. Customize the variable org-yank-adjusted-subtrees and you can use C-y instead of org-paste-subtree in the example above.

For me this was especially useful when I wanted to promote all subtrees under one toplevel.


The problem you described can also be solved with the functions outline-promote and outline-demote.

EDIT: Thanks for the feedback. Just adding to my answer, I've discovered that there also exist functions org-promote-subtree and org-demote-subtree.


Whether or not the subtrees are visible, if you

  • position the cursor at the beginning of the first headline,
  • you are running with Transient-Mark mode enabled (the default),
  • mark the whole thing as your region so that it is highlighted,
  • do M-right,

all of the headlines (and their subtrees) should be demoted one level. If that is not how your setup is working, something is broken: you should investigate the situation and fix it.

  • 1
    I'm having a similar issue as the OP, and posted an up to date question with an MCVE at emacs.stackexchange.com/q/56155/15483 in hopes to find a fix.
    – bgoodr
    Commented Mar 14, 2020 at 21:45
  • 1
    @bgoodr: Try M-right and M-left instead of M-S-right and M-S-left. I think I got that wrong above.
    – NickD
    Commented Mar 14, 2020 at 22:22
  • Edited the answer to fix that. Sorry for the confusion I caused and thanks for pointing it out.
    – NickD
    Commented Mar 14, 2020 at 22:31
  • Thank you too. I've marked your answer to emacs.stackexchange.com/q/56155/15483 and updated that question accordingly with Update 1 to indicate my opinions on the defect here.
    – bgoodr
    Commented Mar 15, 2020 at 17:18

Latest release (develop branch) of Spacemacs has the functions org-promote-subtree and org-demote-subtree that works perfectly. They can be triggered via , s h and , s l, respectively, by keeping cursor on the root of the sub-tree.

I also find it convenient to select region in org file and promote/demote outlines within scope of selection. This can be done by using org-do-promote and org-do-demote functions.

Your Answer

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

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