org-agenda-files list 中使用相对路径出错

发现org-agenda-files list中添加一个目录, 使用相对路径 (setq org-agenda-files '("gtd")) 的话, 打开 org-agenda 时会报错 “org-agenda-get-day-entries: Agenda file /Users/xxx/org/gtd is not in Org mode”.

但是如果使用绝对路径就不会, 如 (setq org-agenda-files '("/Users/xxx/gtd")). 对单个文件(而非目录) 使用相对路径则不会.

从报错信息来看, 路径还是能展开的, 猜想是用 org-agenda-file-regexp match之前 就调用了org-agenda-get-day-entries

但苦于不太懂elisp, 不知道具体哪里出了问题. 向大家求助 版本是 org mode 9.6.1

感觉你期望的相对路径应该是相对 org-directory,根据 org-agenda-files 源码,如果列表中是文件夹,就不 expand-file-name,建议还是自己手动 expand 一下

(defun org-agenda-files (&optional unrestricted archives)
  "Get the list of agenda files.
Optional UNRESTRICTED means return the full list even if a restriction
is currently in place.
When ARCHIVES is t, include all archive files that are really being
used by the agenda files.  If ARCHIVE is `ifmode', do this only if
`org-agenda-archives-mode' is t."
  (let ((files
	 (cond
	  ((and (not unrestricted) (get 'org-agenda-files 'org-restrict)))
	  ((stringp org-agenda-files) (org-read-agenda-file-list))
	  ((listp org-agenda-files) org-agenda-files)
	  (t (error "Invalid value of `org-agenda-files'")))))
    (setq files (apply 'append
		       (mapcar (lambda (f)
				 (if (file-directory-p f)
				     (directory-files
				      f t org-agenda-file-regexp)
				   (list (expand-file-name f org-directory))))
			       files)))
    (when org-agenda-skip-unavailable-files
      (setq files (delq nil
			(mapcar (lambda (file)
				  (and (file-readable-p file) file))
				files))))
    (when (or (eq archives t)
	      (and (eq archives 'ifmode) (eq org-agenda-archives-mode t)))
      (setq files (org-add-archive-files files)))
    files))

感谢! 测试了一下那个 lambda 函数, 懂 setq files 这段的逻辑了.

确实不支持相对于org-directory的路径, 如果 f = “gtd”, (file-directory-p f) 会返回 nil

文档也没有保证这一点, 是我脑补了 :sweat_smile: