org roam 刷新 org id 属性

最近在使用 Org Roam 的时候遇到一个问题:在我同步两台电脑的文档的时候,导出的文档不能自动判断链接中的文章,查看了一下方法的说明,主要是因为在不能正确查找对应的 Org Id 的文件,而导致这个的原因是因为在 org-id-locations-file 中没有对应的记录。

Org Mode 中 org-id-locations-file 默认配置为 ~/.emacs.d/.org-id-locations

仅仅配置上面的参数依旧不能正确导出文档,还需要通过调用 org-id-update-id-locations 方法重新生成对应的 org-id-locations-file ,才能解决缺失的问题。

查看 org-id.el 源码中的设计,发现在调用这个的过程中,会传入 6 个参数,但是从说明中只能看到 其中 4 个。

This will scan all agenda files, all associated archives, and all files currently mentioned in `org-id-locations'. When FILES is given, scan also these files.

从上面的说明中可以知道 4 个参数指向的路径会影响扫描的结果:

  1. org-agenda-files 中配置的文件
  2. org-agenda-files 关联的归档的文件
  3. org-id-locations 中提及的文件
  4. org-id-update-id-locations 方法中传入的文件

另外还有 2 个文件没有在说明中提到,但是看源码的时候能看到传入的参数中其实还有 2 参数指向的路径会影响结果:

  1. org-id-extra-files
  2. org-id-files

所以 org-id-update-id-locations 方法会遍历 6 个变量指向的路径,我们可以通过查看对应的列表中的文件,确认扫描的正确性。

(setq org-id-files (file-expand-wildcards (expand-file-name "roam/*.org" org-directory)))
;; (setq org-id-files (directory-files-recursively (expand-file-name "roam/" org-directory) "\\.org$"))

(let ((files (delete-dups
              (mapcar #'file-truename
                      (append
                       (org-agenda-files t org-id-search-archives)
                       (unless (symbolp org-id-extra-files)
                         org-id-extra-files)
                       org-id-files)))))
  (dolist (file files) (princ (format "%s\n" file))))

说回 org-id.el 的源码中对下面的两个变量的说明,对于英语不好的同学来说,其实是非常不友好的。

  1. org-id-locations 是指的 IDs 和文组成的列表
  2. org-id-files 是指的 包含 IDs 的文件的列表
(defvar org-id-locations nil
  "List of files with IDs in those files.")

(defvar org-id-files nil
  "List of files that contain IDs.")

如果希望扩展使用 org-id-files 变量的话,可以通过几个方法进行扩展。

;; 获取一层文件中所有 .org 结尾的文件
(directory-files roam-directory "\\.org$")
;; 循环遍历文件中所有 .org 结尾的文件
(directory-files-recursively roam-directory "\\.org$")
;; 找到匹配通配符适配的 org 文件
(file-expand-wildcards (concat roam-directory "*.org"))