# \[TIPS\] dynamically add Org-roam files to your agenda file

**URL:** https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122
**Category:** Tips
**Created:** [January 1, 2021, 12:36am UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122 "2021-01-01T00:36:38Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![cool\_ran](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/cool_ran/32/130_2.png) [@cool\_ran](https://org-roam.discourse.group/u/cool_ran)
#### Post date: [January 1, 2021, 12:36am UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/1 "2021-01-01T00:36:39Z")

</div>

Dear folks:

An org-roam user (lld2001) [post](https://emacs-china.org/t/org-roam/15659) a very useful function to dynamically  
add Org-roam files that contain TODO to your agenda files.

```
(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)

```

I find it is useful and hope it can be useful to you as well.

---

<div class="post-metadata">

### Author: ![d12frosted](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/d12frosted/32/278_2.png) [@d12frosted](https://org-roam.discourse.group/u/d12frosted)
#### Post date: [January 16, 2021, 10:25am UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/2 "2021-01-16T10:25:12Z")

</div>

Thank you for sharing it. The problem with this approach is that (a) you can’t plug it into existing pile of notes and (b) messing up with your customize file leads to broken agenda.

This post motivated me to share how I approach this problem that I am using for a month already and super happy about it’s performance. You can read detailed description on my [blog](https://d12frosted.io/posts/2021-01-16-task-management-with-roam-vol5.html). The code is available as a [GitHub Gist](https://gist.github.com/d12frosted/a60e8ccb9aceba031af243dff0d19b2e).

TL;DR - in the `before-save-hook` current buffer is traversed for existence of any TODO entires and `Project` tag is either added or removed from `#+ROAM_TAGS` property. Now, `org-agenda` is adviced before to set the value of `org-agenda-files` to the list of files with `Project` tag (quieried from db, which is enourmously fast).

There is also a snipped to use for migration. This way all required information is always there, in your files and can be easily reconstructed. That being said, proposed solution can be easily adapted to `dynamic-agenda-files` approach.

Hope someone finds it useful 🙂

---

<div class="post-metadata">

### Author: ![S\_Fabris](https://avatars.discourse-cdn.com/v4/letter/s/a8b319/32.png) [@S\_Fabris](https://org-roam.discourse.group/u/S_Fabris)
#### Post date: [April 15, 2021, 10:43am UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/3 "2021-04-15T10:43:57Z")

</div>

This code snippet for collecting files with todos has greatly impacted my workflow! Thanks for sharing.

I am just trying to figure out how this would work with org-roam V2. ROAM\_TAGS have been dropped and from the code it seems that FILETAGS will only get stored in the database if there are headline nodes with ID that inherit the tag. And even if this would work, every todo in the agenda woud be tagged with “Project”, adding visual clutter.

Have you adapted this for the new version already? Would it make sense to use a note that is being linked to by every file that contains todos and then query the database for backlinks?

---

<div class="post-metadata">

### Author: ![nobiot](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/nobiot/32/159_2.png) [@nobiot](https://org-roam.discourse.group/u/nobiot)
#### Post date: [April 15, 2021, 4:00pm UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/4 "2021-04-15T16:00:34Z")

</div>

Hi @S_Fabris

I cannot contribute to @cool_ran’s script, but wanted to respond to two points you commented about V2.

> [@S\_Fabris](#):
>
> it seems that FILETAGS will only get stored in the database if there are headline nodes with ID that inherit the tag

I have been using V2 every day for work for a couple of weeks now; FILETAG just works without headline nodes.  
Most of my org files do not have headlines. I use FILETAG as a category, like Meeting, Reference, etc. No issue.

> [@S\_Fabris](#):
>
> every todo in the agenda woud be tagged with “Project”, adding visual clutter.

I think this is largely related to how you use/customise agenda (I do not show any tags in my agenda view; I just use them as search keys)… You could also look to control how file-level tags get inherited by the looks of [this Org documentation](https://orgmode.org/manual/Tag-Inheritance.html).

> To limit tag inheritance to specific tags, or to turn it off entirely, use the variables `org-use-tag-inheritance` and `org-tags-exclude-from-inheritance` .

I don’t use these variables so I cannot be 100% certain, but it’s probably worth looking into.

---

<div class="post-metadata">

### Author: ![S\_Fabris](https://avatars.discourse-cdn.com/v4/letter/s/a8b319/32.png) [@S\_Fabris](https://org-roam.discourse.group/u/S_Fabris)
#### Post date: [April 19, 2021, 12:58pm UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/5 "2021-04-19T12:58:04Z")

</div>

Thanks for the hint to org-use-tag-inheritance, this keeps the agenda view clean as I do not use tags for other purposes than marking files with todos inside.

---

<div class="post-metadata">

### Author: ![S\_Fabris](https://avatars.discourse-cdn.com/v4/letter/s/a8b319/32.png) [@S\_Fabris](https://org-roam.discourse.group/u/S_Fabris)
#### Post date: [April 23, 2021, 8:14am UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/6 "2021-04-23T08:14:02Z")

</div>

> [@nobiot](#):
>
> I have been using V2 every day for work for a couple of weeks now; FILETAG just works without headline nodes.  
> Most of my org files do not have headlines. I use FILETAG as a category, like Meeting, Reference, etc. No issue.

After some time testing, this does not work for me. Filetags are somehow not consistently added to the database. It worked for the some daily files with tasks and for some the caching function does not add the filetags to the db entry.

However, the modified code from @d12frosted works flawlessly in adding the tags and retrieving them from the db.

Has anyone else used filetags successfully with V2?

---

<div class="post-metadata">

### Author: ![nobiot](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/nobiot/32/159_2.png) [@nobiot](https://org-roam.discourse.group/u/nobiot)
#### Post date: [April 23, 2021, 6:06pm UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/7 "2021-04-23T18:06:10Z")

</div>

> [@S\_Fabris](#):
>
> worked for the some daily files with tasks and for some the caching function does not add the filetags to the db entry.

This issue you experienced might be caused by [this technical issue](https://github.com/org-roam/org-roam/issues/1470), which has been resolved.

---

<div class="post-metadata">

### Author: ![S\_Fabris](https://avatars.discourse-cdn.com/v4/letter/s/a8b319/32.png) [@S\_Fabris](https://org-roam.discourse.group/u/S_Fabris)
#### Post date: [April 28, 2021, 11:26am UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/8 "2021-04-28T11:26:11Z")

</div>

> [@nobiot](#):
>
> This issue you experienced might be caused by [this technical issue](https://github.com/org-roam/org-roam/issues/1470), which has been resolved.

That’s it! Everything working now!

---

<div class="post-metadata">

### Author: ![KSS](https://avatars.discourse-cdn.com/v4/letter/k/a587f6/32.png) [@KSS](https://org-roam.discourse.group/u/KSS)
#### Post date: [May 8, 2021, 9:57pm UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/9 "2021-05-08T21:57:11Z")

</div>

This is a very interesting idea for workflow that might work for me well.  
I’m currently trying to make [the code](https://gist.github.com/d12frosted/a60e8ccb9aceba031af243dff0d19b2e) work at least partially with org-roam v2.

What I want is to add to `org-agenda-files` files with “Project” tag. This is implemented by those two functions:

```
(defun vulpea-project-files ()
  "Return a list of note files containing Project tag."
  (seq-map
   #'car
   (org-roam-db-query
    [:select file
     :from tags
     :where (like tags (quote "%\"Project\"%"))])))

(defun vulpea-agenda-files-update (&rest _)
  "Update the value of `org-agenda-files'."
  (setq org-agenda-files (vulpea-project-files)))

```

When I run `vulpea-project-files` function, I receive the following error:  
`EmacSQL had an unhandled condition: "no such column: file"`

I tried to investigate the structure of `org-roam.db` with `.schema` command to understand which column name should I use. Here is what I got:

 ![2021-05-08-174636_1920x1034_scrot](https://global.discourse-cdn.com/free1/uploads/orgroam/original/1X/a53b2c45bfd2f23eedfdacde3848f10680b6bcb9.png)

Given this structure, shouldn’t it be working as expected? (I haven’t used sql in my life, but it looks that there is a column with name `file`).

Thank you

---

<div class="post-metadata">

### Author: ![d12frosted](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/d12frosted/32/278_2.png) [@d12frosted](https://org-roam.discourse.group/u/d12frosted)
#### Post date: [May 9, 2021, 6:57am UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/10 "2021-05-09T06:57:44Z")

</div>

I will upgrade that for V2 (as well as other posts).

---

<div class="post-metadata">

### Author: ![d12frosted](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/d12frosted/32/278_2.png) [@d12frosted](https://org-roam.discourse.group/u/d12frosted)
#### Post date: [May 10, 2021, 8:22am UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/11 "2021-05-10T08:22:43Z")

</div>

The problem here is that scheme was changed in V2. But the good thing, I’ve updated my [post](https://d12frosted.io/posts/2021-01-16-task-management-with-roam-vol5.html). In short the query should look like this:

```
(defun vulpea-project-files ()
  "Return a list of note files containing 'project' tag." ;
  (seq-uniq
   (seq-map
    #'car
    (org-roam-db-query
     [:select [nodes:file]
      :from tags
      :left-join nodes
      :on (= tags:node-id nodes:id)
      :where (like tag (quote "%\"project\"%"))]))))

```

Please let me know if that works for you!

---

<div class="post-metadata">

### Author: ![KSS](https://avatars.discourse-cdn.com/v4/letter/k/a587f6/32.png) [@KSS](https://org-roam.discourse.group/u/KSS)
#### Post date: [May 16, 2021, 2:56am UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/12 "2021-05-16T02:56:10Z")

</div>

Hey @d12frosted,  
your code works flawlessly!

Thank you so much for your effort in sharing your workflow. This is valuable.

---

<div class="post-metadata">

### Author: ![MBuchaus](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/mbuchaus/32/43_2.png) [@MBuchaus](https://org-roam.discourse.group/u/MBuchaus)
#### Post date: [July 29, 2021, 5:21pm UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/13 "2021-07-29T17:21:55Z")

</div>

Slight mod that I had to figure out to keep specific files in the agenda. As the functions does’t append, it overwrites. Please Educate me of a better way to do this…

```auto
(setq marty/org-agenda-files (list
       (concat org-directory "Tasks.org")
       (concat org-directory "Habits.org")
       (concat org-directory "Calendar.org")
       (concat org-directory "contacts.org")
       (concat org-directory "Someday.org")
       (concat org-directory "0mobile.org")
       "~/.cache/calendar/google.org"
       "~/.cache/calendar/personal.org"))

  (setq org-agenda-files marty/org-agenda-files)

(defun vulpea-agenda-files-update (&rest _)
  "Update the value of `org-agenda-files'."
  (setq org-agenda-files
        (append marty/org-agenda-files (vulpea-project-files))))

```

---

<div class="post-metadata">

### Author: ![d12frosted](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/d12frosted/32/278_2.png) [@d12frosted](https://org-roam.discourse.group/u/d12frosted)
#### Post date: [July 30, 2021, 5:40am UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/14 "2021-07-30T05:40:45Z")

</div>

Sure, the method I described simply overrides whatever you had in `org-agenda-files`. If you wish it to always contain some values you have two options:

1. A method you described with a separate list of agenda files that is concatenated with project files. Works well even for notes outside `org-roam-directory`.
2. Tag these files with an appropriate tag, so that `vulpea-project-files` result contains them. Doesn’t work if files in question are outside of `org-roam-directory` (like your calendar files).

---

<div class="post-metadata">

### Author: ![MBuchaus](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/mbuchaus/32/43_2.png) [@MBuchaus](https://org-roam.discourse.group/u/MBuchaus)
#### Post date: [July 30, 2021, 12:40pm UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/15 "2021-07-30T12:40:20Z")

</div>

woo i’m 1/8th step past Noob… cool. only took 3 years…

---

<div class="post-metadata">

### Author: ![danderzei](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/danderzei/32/59_2.png) [@danderzei](https://org-roam.discourse.group/u/danderzei)
#### Post date: [August 26, 2021, 1:19am UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/16 "2021-08-26T01:19:40Z")

</div>

Is there a way to hook this to something or advise a function so that it runs every time the database updates?

---

<div class="post-metadata">

### Author: ![d12frosted](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/d12frosted/32/278_2.png) [@d12frosted](https://org-roam.discourse.group/u/d12frosted)
#### Post date: [August 26, 2021, 6:16am UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/17 "2021-08-26T06:16:37Z")

</div>

Sure, you can hook into `org-roam-db-update-file` and `org-roam-db-sync` via `advice-add`, e.g.

```auto
(advice-add 'org-roam-db-update-file :after #'vulpea-agenda-files-update)
(advice-add 'org-roam-db-sync :after #'vulpea-agenda-files-update)

```

I think these two functions should be enough. Though I must ask - why do you want to do it? 🙂 DB gets updated much more often than your list of agenda files gets modified. At least in my experience. So I would get unnecessary reads from DB. And this might lead to performance degradation (though this is mere speculation).

---

<div class="post-metadata">

### Author: ![danderzei](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/danderzei/32/59_2.png) [@danderzei](https://org-roam.discourse.group/u/danderzei)
#### Post date: [August 26, 2021, 9:44am UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/18 "2021-08-26T09:44:37Z")

</div>

Thanks. It is indeed automation overkill - just interested how it would work.

---

<div class="post-metadata">

### Author: ![pablo](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/pablo/32/756_2.png) [@pablo](https://org-roam.discourse.group/u/pablo)
#### Post date: [December 1, 2021, 4:28pm UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/19 "2021-12-01T16:28:44Z")

</div>

The code is fantastic—thanks d12frosted for sharing it.

I’d like to supplement it with a function that checks whether each file in the `org-roam` directory was modified in the last `n` days, so that `org-agenda` lists both files with a TODO element and files modified recently. Unfortunately, I am not able to create such a function. The shell command `find "path-to-org-roam-directory" -mtime -n -ls` finds the files modified in the past `n` days, and perhaps one could pass its output to `shell-command-to-string` to generate a list of the relevant directories, but I’m not sure how to do that, or whether a different approach is more appropriate. Any help would be appreciated.

---

<div class="post-metadata">

### Author: ![pablo](https://yyz2.discourse-cdn.com/free1/user_avatar/org-roam.discourse.group/pablo/32/756_2.png) [@pablo](https://org-roam.discourse.group/u/pablo)
#### Post date: [December 1, 2021, 7:22pm UTC](https://org-roam.discourse.group/t/tips-dynamically-add-org-roam-files-to-your-agenda-file/1122/20 "2021-12-01T19:22:59Z")

</div>

Okay, it looks that I was just missing `split-string`. The following function generates the list of files I wanted:

```auto
(defun ps/org-roam-recent (days)
  "Return list of files modified in the last DAYS."
  (let ((mins (round (* 60 24 days))))
    (split-string
     (shell-command-to-string
      (format
       "find %s -name \"*.org\" -mmin -%s"
       org-roam-directory mins)))))

```
