0

According to the org agenda docs, I should be able to set a custom local option for a given agenda command. In this case, I want to set a custom org-agenda-files variable, which is an explicit example given by the docs:

(setq org-agenda-custom-commands 
  '(("c" "Desk Work" tags-todo "computer" ;; (1) (2) (3) (4)
     ((org-agenda-files '("~/org/widgets.org" "~/org/clients.org")) ;; (5)
      (org-agenda-sorting-strategy '(priority-up effort-down))) ;; (5) cont.
     ("~/computer.html")) ;; (6)
    ;; ...other commands here
    ))

However, when I try this, it doesn't work. My main org-agenda-files is a recursive directory with thousands of org files, and all are being presented in my org-agenda-custom-command despite me trying to set the org-agenda-files for the given command. I suspect the issue is some misunderstanding I have about lisp syntax. I've tried the following:

At the top of my config is

  (setq org-agenda-files
    (directory-files-recursively "~/Dropbox/org" "\\.org$")
    )

Which works properly. I've tried configuring:

  (add-to-list 'org-agenda-custom-commands
        `("dd" "Daily Agenda"
          (
           (org-agenda-files '(seq-filter (lambda(x) (not (string-match "/notes/"(file-name-directory x))))
                (directory-files-recursively "~/Dropbox/org" "\\.org$")
                ))
           (agenda ""
                   (
                    (org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
                    (org-agenda-span 'day)
                    (org-deadline-warning-days 5)
                    (org-super-agenda-groups
                     '((:auto-category t :time-grid t))))))))

This custom command included the files in /notes/.

  (add-to-list 'org-agenda-custom-commands
        `("dd" "Daily Agenda"
          (
           (agenda ""
                   (seq-filter (lambda(x) (not (string-match "/notes/"(file-name-directory x))))
                (directory-files-recursively "~/Dropbox/org" "\\.org$")
                ))
                   (
                    (org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
                    (org-agenda-span 'day)
                    (org-deadline-warning-days 5)
                    (org-super-agenda-groups
                     '((:auto-category t :time-grid t))))))))

This custom command included the files in /notes/.

(add-to-list 'org-agenda-custom-commands
        `("dd" "Daily Agenda"
          (
           (agenda ""
                   (
                    (org-agenda-files (seq-filter (lambda(x) (not (string-match "/notes/"(file-name-directory x))))
                (directory-files-recursively "~/Dropbox/org" "\\.org$")
                ))
                    (org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
                    (org-agenda-span 'day)
                    (org-deadline-warning-days 5)
                    (org-super-agenda-groups
                     '((:auto-category t :time-grid t))))))))

This custom command included the files in /notes/, and is the one I think most matches the syntax given by the example.

I struggle with lisp syntax and putting things in the right spot, but I'm very confused why this isn't working.

What's the proper way to set a custom variable like org-agenda-files for a org-agenda-custom-command?

8
  • 1
    A good recommendation from the Org manual about org-agenda-custom-commands: "As you see, the values and parentheses setting is a little complex. When in doubt, use the customize interface to set this variable—it fully supports its structure."
    – gusbrs
    Mar 15 at 12:49
  • I will try that today, however I'm hoping to update my config file afterwards, and I'm not sure how to extract the result of using the customize interface. I use emacs on several machines throughout the week, and prefer to update and maintain just one config location.
    – Caleb Jay
    Mar 16 at 2:42
  • 1
    You can save the customizations in the customize interface (with the usual C-x C-s), and then later copy the variable and its value to a regular setq, if you prefer. I sometimes do that. I personally set custom-file to something "not on my init.el", don't load it, but have it at hand for one or another occasion like that. I can thus save something from the customize interface to make sure the syntax is correct and, when I'm happy with the value, I just copy the result to my init file.
    – gusbrs
    Mar 16 at 3:08
  • I tried the setup from the first link. It works fine, limiting itself to the two files that are specified as org-agenda-files in the command. Let's hope that the customization interface, as @gusbrs suggested, helps you untangle the forest of parentheses successfully.
    – NickD
    Mar 17 at 3:23
  • 1
    Please consider update your question? I don't see any /notes/ in your last two code snippets. Mar 17 at 13:00

1 Answer 1

1

Try the following - I have not tested it much to make sure that it works as you want, but it at least works well enough to produce an agenda. The main thing I did is I formatted the custom command to conform to the description in the doc string of org-agenda-custom-commands and added comments to the various elements of the structure:

(add-to-list 'org-agenda-custom-commands
    `("dd"                     ;key
      "Daily Agenda"           ;description
      agenda                   ;type
      ""                       ;match - empty string for agenda type
      ;; local settings
      ((org-agenda-files (seq-filter
                            (lambda(x)
                               (not (string-match "/notes/"(file-name-directory x))))
                            (directory-files-recursively "~/Dropbox/org" "\\.org$")))
       (org-agenda-skip-function '(org-agenda-skip-entry-if 'todo 'done))
       (org-agenda-span 'day)
       (org-deadline-warning-days 5)
       (org-super-agenda-groups '((:auto-category t :time-grid t))))))

Try it out and make sure it does not produce any errors. Then start the more arduous process of checking whether it does what you want and fixing it as necessary. You might find it easier to check if you test your filter separately: evaluate it in the *scratch* buffer and make sure that the list of files you get is the one you expect.

Note that because of the "dd" key, you get a two-level menu: C-c a gets you the agenda menu, a d gets you to the second level menu and another d executes the command. The two-level structure is probably not useful here, but the page you linked to has an example of how to have a whole bunch of second-level commands under a given prefix ("d" in this example).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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