Task management with org-roam Vol. 6: Select a person and view related tasks

Posted on January 24, 2021
Updated on July 20, 2022
Tagged as #emacs, #org-roam

In one of the previous articles (Vol. 3 to be precise) we talked about automatic setup of filetags, so each of the task in note related to a person is automatically tagged thanks to tag inheritance. Then, in Vol. 4 we talked about automatic tagging of tasks whenever a person is mentioned either in the title or the body of some task. This all makes org-agenda matching capabilities really useful for when we want to see the list of all tasks related to specific person.

In this article, we are going to write a small utility function that asks user to select a person and then presents and org-agenda buffer with tasks related to selected person.

Believe me, intro is longer than the content!

Change Log:

  • [2021-03-02 Tue]: Update naming convention to match personal configurations.
  • [2021-05-10 Mon]: Update post to reflect changes in org-roam v2. Previous version of this article is available on GitHub.
  • [2022-07-11 Mon]: Adapt code to changes in Org mode and new functions in vulpea. Combination of vulpea-select-from and vulpea-db-query-by-tags-some works faster than generic vulpea-select.

Long story short, here is the function you can bind or call by name using M-x:

(defun vulpea-agenda-person ()
  "Show main `org-agenda' view."
  (let* ((person (vulpea-select-from
                  (vulpea-db-query-by-tags-some '("people"))))
         (node (org-roam-node-from-id (vulpea-note-id person)))
         (names (cons (org-roam-node-title node)
                      (org-roam-node-aliases node)))
         (tags (seq-map #'vulpea--title-to-tag names))
         (query (string-join tags "|")))
    (let ((org-agenda-overriding-arguments (list t query)))
      (org-agenda nil "M"))))

Now some explanations.

  1. This code uses vulpea library1 to select a person. You can achieve the same result without vulpea, of course, but it saves some effort. vulpea-select-from asks the use to select a note from a list of notes, returned by vulpea-db-query-by-tags-some. In this case, we simply present only people notes. The same result can be achieved by using vulpea-select that takes a predicate, but vulpea-db-query-by-tags-some works faster. See Performance section of vulpea documentation.
  2. Once we have a selected vulpea-note, we can get all titles on that file (e.g. main title and aliases). This is important for alias users. For example, in some notes I want use Mr. Frodo instead of Frodo Baggins, but I want to see tasks tagged as @Mr.Forod and @FrodoBaggins at the same time. It’s the same person after all (don’t ask me about Gollum, better use M-x doctor)!
  3. Now we simply convert those names into tags using vulpea--title-to-tag from Vol. 4.
  4. Then we join the tags using | separator into single query string.
  5. The last step is to execute org-agenda with M argument (match for tags, but list only TODO items). In order to pass a query to relevant agenda function, we use org-agenda-overriding-arguments. Not sure if it’s documented anywhere, but you can read the sources of org-agenda to figure out how to use it. dlet here is used for dynamic binding. If you are not using lexical scope, you can use regular let here.

That’s it! Now see it in action, again.

Task Management with org-roam Series

  1. Path to Roam
  2. Categories
  4. Automatic tagging
  5. Dynamic and fast agenda
  6. Select a person and view related tasks
  7. Capture


  1. Yikes, I advertise my own libraries on this blog!↩︎