Org-mode newbie here.

I use the org-agenda-filter pretty heavily as part of my daily agenda workflow. I have a tag for "Work" related TODO items and repeat this operation several times a day:

  1. Pressing C-a a
  2. invoke the org-agenda-filter using /
  3. filter to my tag and TODO items of interest e.g. Work/TODO

I want to create a custom filter command for this and have worked on this so far:

(setq org-agenda-custom-commands
  '(("w" "List Work Tasks"
 ((agenda "" ((org-agenda-span 'week)))
  (org-agenda-filter '("Work/TODO"))))))

When I press C-a w, it asks me to enter my Tag/TODO keywords again. It seems like this code is not able to pass the search terms to org-agenda filter.

What am I doing wrong?

  • In step 1, I don't know what C-a a does. Can you clarify? Do you mean C-c a as described in Activation in the manual? If you really mean C-a a, then tell us what that is bound to: do C-h c C-a a and tell us what it says. Then in step 2, what does '/' do? In my agenda dispatcher, it does Multi-occur which is a text search function, not a tag/TODO search. Please clarify.
    – NickD
    Commented May 28, 2023 at 3:16

1 Answer 1


This seems surprisingly hard to do! The recommended approach seems to be this footnote in the docs. It describes creating custom agenda commands where:

... one of the variables org-agenda-tag-filter-preset, org-agenda-category-filter-preset, org-agenda-effort-filter-preset or org-agenda-regexp-filter-preset [are set] as an option. This filter is then applied to the view and persists as a basic filter through refreshes and more secondary filtering.

Like you, I didn't really want a dedicated org-agenda command, instead to bind to a key for turning on and off a particular filter inside any agenda. In my case, I wanted to toggle a category filter not a tag.

None of the "interactive" org-agenda filter functions support passing in the filter value as an argument, they all either prompt or take the filter value from under the point.

I went looking at the function implementations. org-agenda-filter-by-category is less general than org-agenda-filter, so it was a bit easier to understand. This function updates the variable org-agenda-category-filter and then calls org-agenda-filter-apply with the result. Here's the key bit:

 (setq org-agenda-category-filter
  (list (concat "+" cat)))

On that basis, I wrote a function similar to this:

(defun my/org-agenda-toggle-work ()
 "Toggle excluding work category from the agenda"
 (if org-agenda-category-filter
  (org-agenda-remove-filter 'category)
  (org-agenda-filter-apply (setq org-agenda-category-filter '("-work")) 'category)

And bound it to a key in org-agenda-mode-map. Seems to work!

I think you could do the same thing for a tag filter, but instead set variable org-agenda-tag-filter and pass 'tag as the type.

Overall this seems like an ugly hack that couples too deeply into the implementation of org-agenda filtering. Would like to find a nicer way to do this (for example, extending the interactive function org-agenda-filter to take an optional value argument).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.