0

Let's say I have this in my games.org file:

* Games I own
** Adventures
*** Adventure - Police Quest
*** Adventure - Mixed-Up Mother Goose 

And I want to link to the Adventure - Mixed-up Mother Goose subheader from my other file notes.org.

I would also like to be able to create the header and subheader if it doesn't exist.

Right now I am doing this. So, we are in notes.org and I do:

[[file:games.org::Adventure - Mixed-Up Mother Goose]]

or

[[file:games.org::Adventure - Mixed-Up Mother Goose][Some other name if needed]]

And this works great.

However, when I want to create a link in notes.org to a subheader that doesn't exist in games.org - for example, I have an idea while writing something but I want to create it now it will ask me in the minibuffer whether I want to create this header because it doesn't exist No match - create this as a new heading? (y or n).

And if I say yes, it will be created but as the H1 and not H3. So, if I wanted to create Adventure - Space Quest it will look like this:

* Games I own
** Adventures
*** Adventure - Police Quest
*** Adventure - Mixed-Up Mother Goose 
* Adventure - Space Quest

and not like as I wanted it to look like:

* Games I own
** Adventures
*** Adventure - Police Quest
*** Adventure - Mixed-Up Mother Goose 
*** Adventure - Space Quest

Any idea how to make it work like I want? Perhaps there is some hidden syntax I have to type in the minibuffer or something?

1
  • Once the heading has been created at the wrong level, press M-<right> a couple of times to get it to the right level and switch back to your notes.org buffer to continue.
    – NickD
    Jul 16 at 17:17

1 Answer 1

1

I am unsure if what you are suggesting is possible in the default org implementation. However, it may be possible to hack your way to what you're looking for.

The method you used in your question to create a new heading is invoked via org-link-search. From the source code, this block is relevant:

     ;; Offer to create non-existent headline depending on
     ;; `org-link-search-must-match-exact-headline'.
     ((and (derived-mode-p 'org-mode)
       (eq org-link-search-must-match-exact-headline 'query-to-create)
       (yes-or-no-p "No match - create this as a new heading? "))
      (goto-char (point-max))
      (unless (bolp) (newline))
      (org-insert-heading nil t t)
      (insert s "\n")
      (beginning-of-line 0))

The value 'query-to-create on org-link-search-must-match-exact-headline is what enables the creation of headlines when searches return no matches.

Importantly, the (org-insert-heading nil t t) is what creates your heading. The parameters of this command are (org-insert-heading &optional ARG INVISIBLE-OK TOP). TOP is relevant here, because as the documentation says:

When optional argument TOP is non-nil, insert a level 1 heading,
unconditionally.

So you will want to make this function have nil for this parameter in the search function.[1] I would recommend doing this in a user config rather than the actual source code. I would also set it to a custom command so you do not impact original functionality.

Once you do this, you should be able to define links like [[file:games.org::** Adventure - Mixed-Up Mother Goose]] to generate second level headers, etc.


[1] Alternatively, if you are willing to use a consistent syntax, remove the org-insert-heading line altogether and use a consistent format to define inserted header levels. For example, [[** my headline]] would be inserted as-is, which matches heading level 2 syntax already.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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