集成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)
14赞

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

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

1赞

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

提示symbol’s function definition is void: union 问下有啥解决方法吗

1赞

我也遇到了这个问题,暂时没精力去 debug。 d12frosted 给出了类似的解决办法,可供参考。另外 Org-roam 最近在准备一次大的的升级,可以等新版本出来以后再折腾。

很奇怪的问题, 我使用org-roam-capture追加的内容, 会添加到文档的首行, 而不是末行. 不知道中哪儿有问题, 也不知道怎么解决.

因为union是common lisp 的一个函数,在emacs中通过cl-union来模拟这个函数。

所以把union换成cl-union就可以了

多谢楼主,已经在使用这个方案了。非常棒。 稍微有些小瑕疵,不过不影响使用

多谢回复,可以用了,同时感谢楼主

谢谢补充,union在我这是cl-seq.el文件中,换成cl-union吧

最新遇到了个问题,有时候会出现agenda视图不能用,我的是doom emacs,执行org-agenda,会出现org-check-agenda-file: Wrong type argument: stringp, nil错误。然后我把楼主的配置去掉,重启就又好了

我也是在doom emacs下用,没出现这个问题。看下你的org-agenda-files,还可检查下dynamic-agenda-files的值。我是手动设置org-agenda-files固定几个文件作日常任务。然后动态配合其他笔记作任务管理。

可能是doom的问题吧,我找到了类似的国外友人的一个实现方法,https://d12frosted.io/posts/2021-01-16-task-management-with-roam-vol5.html

我昨天也刚好读到,不过由于我的是静态与动态agenda files相结合,暂时没用上。