Ironing out kinks in org-roam-extract-subtree

Refactoring a header within a current node into a separate file-node is a very common action for me. The function org-roam-extract-subtree seems built for exactly this purpose. However, I have been encountering problems or unexpected behaviors. I will add to this thread as I observe and enumerate all the issues. Meanwhile, here is the first issue Here is the list:

  1. First paragraph of subtree is treated strangely. The first paragraph is placed one line above #+title: in the newly-created file-node.
  2. What template, if any, does the newly-created file-node use? For example, I’d like to insert :CREATED: in the PROPERTIES drawer of the file-node if subheader doesn’t already have this property. If subheader already has this property, I’d like to insert :MODIFIED:.
  3. Is it possible to open the newly-created file-node in a new window (perhaps a preference variable whose value can be set by the user)? One reason I want to see it in a new window is to confirm that the file has indeed been created with the appropriate content. Often what is being refactored is precious text. Some visual feedback confirming that it has been saved in its full form can be reassuring.
  4. When extracting a subtree from a non-roam org file, I’d like it to create the node-file in my org-roam-directory. Currently, it seems to create the node-file in the directory in which the original file is found. And, there is some strange behavior after the extraction (I haven’t fully characterized the behavior but something is off (sorry for that vague description… I’ll add detail when I get the chance)).

I think that captures my major concerns/issues.


I believe Issue #1 is a problem with org-roam-promote-entire-buffer. To recreate, follow these steps:
a. Create a new .org file in your org-roam-directory and insert the following text:

* asfasdfasfsdasdfa
:CREATED:  [2022-02-26 Sat 13:24]

b. M-x org-roam-promote-entire-buffer

I am writing my own version of extract-subtree. Below is a version that appears to address Issue 4 and, in a clunky way, Issue 1. I took chunks of code from the current version of org-roam-extract-subtree from Github. I will post again when I eventually address Issues 3 and 4. The end-product is a non-elegant patched-up solution — good enough, I hope, until the real org-roam-extract-subtree is fixed in a future release.

  (defun aa/roam-extract-subtree ()
      (org-back-to-heading-or-point-min t)
      (when (bobp) (user-error "Already a top-level node, possibly in a narrowed buffer"))
      (let* ((target-path (expand-file-name org-roam-directory))
             (file-path (concat target-path "/" (aa/slug-maker (substring-no-properties (org-get-heading t t))) ".org")))
        (when (file-exists-p file-path)
          (user-error "%s exists. Aborting" file-path))
        (when (string-prefix-p target-path (buffer-file-name))
        (with-current-buffer (find-file-noselect file-path)
        ;;; --- a crude fix to correct placement of #+title: ---
          (search-forward "#+title:")
        ;;; -----------------------------------------------

  (defun aa/slug-maker (thestring)
    ;;  (interactive "r")
      "[^a-z0-9_-]" ""
       "\s+" "_"
       (downcase thestring)
       )) "[\t\n\r\s_-]+" "[\t\n\r\s_-]+")

PR is pending for #1:

Updated to org-roam 2022-03-15.637 from MELPA and #1 still an issue.

The PR has not been merged. I’ll update it and resubmit.

Sorry for the delay on the review @jmay, I think there are a couple of issues that are inherited from the original code, I’ll write a longform comment on the issue today.