GLee
GLee

Reputation: 5093

Org mode agenda: Reuse code in block agenda

I have an org-agenda-custom-commands like so:

("u" "Unscheduled TODO"
           todo ""
           ((org-agenda-overriding-header "\nUnscheduled TODO")
           (org-agenda-skip-function '(org-agenda-skip-entry-if
                                              'scheduled 'deadline 'timestamp
                                              'todo '("BACKBURNER")))))

I would like to reuse the todo part of this agenda view in other block agenda views. So for instance defining an unscheduled-todo list for reuse (pseudocode, not working):

(setq unscheduled-todo '((org-agenda-overriding-header "\nUnscheduled TODO")
                           (org-agenda-skip-function '(org-agenda-skip-entry-if
                                                       'scheduled 'deadline 'timestamp
                                                       'todo '("BACKBURNER")))))
(setq org-agenda-custom-commands
        '(("u" "Unscheduled TODO"
            (todo "" unscheduled-todo))
          ("c" "Complete View"
            ((agenda "")
             (todo "" unscheduled-todo))))

How do I get the above code to work? I think I have a fundamental misunderstanding of how and when the code and lists are getting evaluated. I've tried a number of configurations of ' and () in both setq and org-agenda-custom-commands, along with append to create lists, but I'd also like to understand what's going on here.

Upvotes: 1

Views: 390

Answers (1)

NickD
NickD

Reputation: 6412

Here's an implementation along the lines of my comment (although I think you really don't need a macro here: a function does just as well or better):

(defun unscheduled-todo ()
    '((org-agenda-overriding-header "\nUnscheduled TODO")
      (org-agenda-skip-function '(org-agenda-skip-entry-if
                                  'scheduled 'deadline 'timestamp
                                  'todo '("BACKBURNER")))))

(setq org-agenda-custom-commands
      ; N.B. the character following this comment is a *backquote* 
      ; (the key to the left of the 1 key on a standard US keyboard);
      ; it is *NOT* a quote (the key to the left of the ENTER key
      ; on a standard US keyboard).
      `(("u" "Unscheduled TODO"
         todo "" ,(unscheduled-todo))
        ("c" "Complete View"
            ((agenda "")
             (todo "" ,(unscheduled-todo))))))

I hope it's correct now (I had to fix it a couple of bugs) but it's only lightly tested.

Note that this uses the backquote mechanism to quote most of the value in the setq of org-agenda-custom-commands while allowing the evaluation of the call to the macro using the comma mechanism.

EDIT: As @Rorschach points out in a (now deleted) comment, I'm overcomplicating things. You still need backquote and comma, but you can use the variable you defined:

(setq unscheduled-todo
    '((org-agenda-overriding-header "\nUnscheduled TODO")
      (org-agenda-skip-function '(org-agenda-skip-entry-if
                                  'scheduled 'deadline 'timestamp
                                  'todo '("BACKBURNER")))))

(setq org-agenda-custom-commands
      ; N.B. the character following this comment is a *backquote* 
      ; (the key to the left of the 1 key on a standard US keyboard);
      ; it is *NOT* a quote (the key to the left of the ENTER key
      ; on a standard US keyboard).
      `(("u" "Unscheduled TODO"
         todo "" ,unscheduled-todo)
        ("c" "Complete View"
            ((agenda "")
             (todo "" ,unscheduled-todo)))))

The backquote/comma mechanism allows the evaluation of a spliced-in variable just as well as it allows the evaluation of a spliced-in function call.

Upvotes: 4

Related Questions