集成org-roam和任务管理

用org-roam管理笔记一段时间了,记录、捕获、文献管理都用得舒服,就是任务管理不方便。我原来的agenda是固定在几个文件中(手动设置org-agenda-files),使用org-roam后会生成大量org,如果全部设置为agenda目录,则生成agenda太慢也太乱。

于是提出如下想法:

  1. 固定的agenda文件仍然在org-agenda-files中
  2. 由一个变量维护动态agenda文件,在任何org文件中,当org entry状态变为todo类时,自动把文件加到该变量,当任务完成后,如果该文件中所有任务都完成,则从变量去除org文件
  3. 变量保存到custom中(不知道更好办法)

经过折腾,如下代码暂时可用:

(defvar dynamic-agenda-files nil
  "dynamic generate agenda files list when changing org state")

(defun update-dynamic-agenda-hook ()
  (let ((done (or (not org-state) ;; nil when no TODO list
                  (member org-state org-done-keywords)))
        (file (buffer-file-name))
        (agenda (funcall (ad-get-orig-definition 'org-agenda-files)) ))
    (unless (member file agenda)
      (if done
          (save-excursion
            (goto-char (point-min))
            ;; Delete file from dynamic files when all TODO entry changed to DONE
            (unless (search-forward-regexp org-not-done-heading-regexp nil t)
              (customize-save-variable
               'dynamic-agenda-files
               (cl-delete-if (lambda (k) (string= k file))
                             dynamic-agenda-files))))
        ;; Add this file to dynamic agenda files
        (unless (member file dynamic-agenda-files)
          (customize-save-variable 'dynamic-agenda-files
                                   (add-to-list 'dynamic-agenda-files file)))))))

(defun dynamic-agenda-files-advice (orig-val)
  (union orig-val dynamic-agenda-files :test #'equal))

(advice-add 'org-agenda-files :filter-return #'dynamic-agenda-files-advice)
(add-to-list 'org-after-todo-state-change-hook 'update-dynamic-agenda-hook t)
10赞

很好用。Agenda 集中管理任务的优势可以和 Org-roam 的发散思维优势合并在一起。

把楼主的代码,也搬运到了 Org-roam 的英文社区,让更多的人用到你的函数。

我现在是只用一个task文件, 添加新任务通过org-roam-capture往task.org中来添加.