Earlier in v1 when titles were basically notes, vs title with ID is a note, one could rename the title and the filename used to change. After v2 implementation when I change title I see the filename is still the same.
This work great for me. one little thing: from a UX perspective, I found it confusing that after renaming #+title and hitting C-x C-s the minibuffer prints a message saying that the buffer has been saved to /path/to/org-roam/old-title.org (even though it actually saves it to /path/to/org-roam/new-title.org as one would expect):
Saving file /path/to/org-roam/old-title.org...
Wrote /path/to/org-roam/old-title.org
I replaced the last line of code with the following two lines, which seems to fix the issue
(set-buffer-modified-p t)
(save-buffer))))
After hitting C-x C-s the minibuffer now prints
Saving file /path/to/org-roam/old-title.org...
Wrote /path/to/org-roam/old-title.org
Saving file /path/to/org-roam/new-title.org...
Wrote /path/to/org-roam/new-title.org
Disclaimer: I am new to elisp, so please correct me if I got anything wrong. Or if there is a better way to improve this.
Thanks for code sharing and for keeping the date prefix. After testing it I realized that it messes up the newly created nodes and prevents them from getting the date prefix when you hit C-c C-c to confirm the captured node. Is there a way to modify this code to make it distinguish newly created nodes from old ones?
Nobiot wrote that they âwould not want Emacs to automatically do anything to Link A and Link Bâ ( Org-Roam V2 rename file or #+TITLE - #4 by nobiot ), and I agree that automatic rewriting of backlinks or link descriptions is not universally desirable.
In contrast I think lots of people might want to change the title of a note: they initially used some dummy or temporary title, then they want to change it, and they want the filename to reflect that change, while keeping the org-roam prefix. Doing this by hand is tedious, and a helper function like the one suggested by quolpr in Does renaming title no longer renames the filename? - #8 by quolpr is both simple to implement and very useful.
I made a few changes on quolprâs code:
Use rename-visited-file which is the newer shorthand for the common sequence:
Avoid depending on a fresh org-roam DB update
In my setup, even with org-roam-db-autosync-mode enabled, the org-roam DB was not always updated immediately after editing #+title: and saving. Since org-roam-node-at-point and org-roam-node-slug read from the DB, they can return a stale title/slug unless I force a refresh:
(org-roam-db-update-file (buffer-file-name))
Instead, I chose to read #+title: directly from the current buffer using the org-element API.
Code:
(defun my/org-buffer-title ()
"Return the value of #+title: in the current buffer, or nil if none."
(let ((ast (org-element-parse-buffer 'element)))
(org-element-map ast 'keyword
(lambda (kw)
(when (string-equal (org-element-property :key kw) "TITLE")
(org-element-property :value kw)))
nil
t)))
(defun my/org-roam-rename-to-new-title ()
"Rename the current org-roam file based on the current buffer #+title:.
Keeps an existing 14-digit timestamp prefix like 20240211123456-."
(interactive)
(require 'org-roam-node)
(when-let* ((old-file (buffer-file-name))
(_ (org-roam-file-p old-file))
(title (my/org-buffer-title))
(slug (org-roam-node-slugify title))
(base (file-name-base old-file))
(prefix (if (string-match "\\`\\([0-9]\\{14\\}\\)-" base)
(concat (match-string 1 base) "-")
""))
(new-file (expand-file-name (concat prefix slug ".org")
(file-name-directory old-file))))
(unless (file-equal-p old-file new-file)
(when (buffer-modified-p)
(save-buffer))
(rename-visited-file new-file))))
I didnât tie it to a hook because I prefer to call it manually.