(分享) Org-roam 的 Title 和文件名同步命令

从某处抄来的, 因为我用 Zettelsktan 笔记方法, 我会经常修改知识卡片的编号, 有了这个命令, 绑定到某键位上, 很方便.

(defun my-rename-roam-file-by-title (&optional path)
  "Rename file in current buffer, based on its Org
,#+title property.

Can also take a file PATH instead of current buffer."
  (interactive)
  (unless path
    (setq path (buffer-file-name)))
  (unless (equal "org" (file-name-extension path))
    (user-error "File doesn't end in .org: %s" path))
  (let* ((visiting (find-buffer-visiting path))
         (on-window (and visiting (get-buffer-window visiting)))
         (slug
          (with-current-buffer (or visiting (find-file-noselect path))
            (goto-char (point-min))
            (let ((node (org-roam-node-at-point t)))
              (unless (org-roam-node-title node)
                (user-error "Node not yet known to org-roam DB"))
              (org-roam-node-slug node))))
         (new-path (expand-file-name (concat slug ".org")
                                     (file-name-directory path))))
    (if (equal path new-path)
        (message "Filename already correct: %s" path)
      (if (and visiting (buffer-modified-p visiting))
          (message "Unsaved file, letting it be: %s" path)
        (unless (file-writable-p path)
          (error "No permissions to rename file: %s" path))
        (unless (file-writable-p new-path)
          (error "No permissions to write a new file at: %s" new-path))
        ;; Kill buffer before renaming, to be safe
        (when visiting
          (kill-buffer visiting))
        (rename-file path new-path)
        (prog1 (message "File %s renamed to %s"
                        (file-name-nondirectory path)
                        (file-name-nondirectory new-path))
          ;; Visit the file again if you had it open
          (when visiting
            (let ((buf (find-file-noselect new-path)))
              (when on-window
                (set-window-buffer on-window buf)))))))))

7 个赞