4

Problem

The default agenda-list-view separates the todo items of the current week by days and sort them by time within each day if there are timestamps. Instead, I want to combine all the todo items without any timestamps.

Motivation

The power of weekly plan is well known. The default agenda view agenda-list-view however does not allow one to easily see what has been achieved and what has to be done in the current week, as what a Kanban board would be able to do. There is org-kanban, but it is not as powerful as what org-agenda can offer and cannot pick items from the current week.

Example

Given the following Org file stored as file_name.org

* TODO No Timestamp
* TODO Deadline last Sunday
SCHEDULED: <2020-07-04 Sat> DEADLINE: <2020-07-05 Sun>
* NEXT Scheduled for last Sunday
SCHEDULED: <2020-07-05 Sun>
* DONE Scheduled for this Monday
SCHEDULED: <2020-07-06 Mon>
* TODO Scheduled for this Tuesday 
SCHEDULED: <2020-07-07 Tue>
* TODO Scheduled for next Monday
SCHEDULED: <2020-07-13 Mon>

Assuming today is <2020-07-08 Wed> I'd like to have an agenda view that only shows the DONE/NEXT/TODO items from the current week, sorted by todo state:

file_name:   DONE Scheduled for this Monday
file_name:   NEXT Scheduled for last Sunday
file_name:   TODO Scheduled for this Tuesday

Details

Note that only items satisfying one of the two conditions are included in the desired agenda view:

  • TODO items that are scheduled for previous weeks or for the current week.
  • DONE items scheduled for current week.

This implies the following items are excluded:

  • DONE items scheduled for a day before the current week.
  • Items whose deadlines are before the current week.
  • Items scheduled for a day after the current week.

What would be the best way to achieve this? I played around with the custom agenda view using tags-todo, but couldn't find a way to pick only the todo items from the current week. The closest command I can find for picking the todo items from the current week is something like tags-todo "SCHEDULED>=\"<-7d>\"SCHEDULED<=\"<+7d>\"" but this is not exactly what I want.

  • This needs some additional specification: any TODO label? any kind of planning info (SCHEDULED, DEADLINE, plain timestamp)? What do you want to do about entries with no timestamps? How do you want the output sorted? Assuming that you can answer these questions, you should be able to do all that with a custom agenda view though. – NickD Jul 10 at 15:40
  • Hi, I added more a precise description of what I exactly want. I already played around with the custom agenda view, but couldn't find the exact command to pick the TODO items from the current week. It would be great if you could help me with this. – Jae Jul 11 at 22:12
  • 2
    Consider having a look at github.com/alphapapa/org-super-agenda. It's highly customizable. – Toon Claes Jul 17 at 5:39
3

As Toon Claes suggested I checked out org-super-agenda and came up with the following solution. Hope this could be useful for some people.

(defun start-and-end-date-of-the-week (date)
    (-let* (((month day year) date)
        (org-today (format "%d-%02d-%02d" year month day))
        (today-absolute (org-time-string-to-absolute org-today))
        (remaining-days-of-the-week (mod (- (calendar-week-end-day) (calendar-day-of-week date)) 7))
        (first-day-of-the-week-absolute (1+ (- today-absolute (calendar-day-of-week date))))
        (last-day-of-the-week-absolute (+ today-absolute remaining-days-of-the-week))
        (first-day-of-the-week (calendar-gregorian-from-absolute first-day-of-the-week-absolute))
        (last-day-of-the-week (calendar-gregorian-from-absolute last-day-of-the-week-absolute))
        ((month1 day1 year1) first-day-of-the-week)
        ((month2 day2 year2) last-day-of-the-week)
        (start-date (format "%d-%02d-%02d" year1 month1 day1))
        (end-date (format "%d-%02d-%02d" year2 month2 day2)))
      (list start-date end-date)))

(setq org-agenda-custom-commands
    '(("k" "Kanban View"
       ((todo "DONE" ((org-agenda-sorting-strategy '(priority-down))))
        (todo "NEXT" ((org-agenda-sorting-strategy '(priority-down))))
        (todo "TODO" ((org-agenda-sorting-strategy '(priority-down)))))
       ((org-super-agenda-groups
         (-let* (((start-date end-date) (start-and-end-date (calendar-current-date))))
           `((:name none
            :not (:and (:not (:and (:tag "work"
                             :todo "DONE"
                             :scheduled (after ,start-date)
                             :not (:deadline (before ,start-date))
                             :not (:tag "drill")))
                     :not (:and (:tag "work"
                              :todo "NEXT"
                              :scheduled (before ,end-date)
                              :not (:deadline (before ,start-date))))
                     :not (:and (:tag "work"
                              :todo "TODO"
                              :scheduled (before ,end-date)
                              :not (:deadline (before ,start-date))
                              :not (:regexp "+[12][dw]"))))))
         (:discard (:anything t)))))))))

N.B. The implementation requires the dash package.

| improve this answer | |
  • Nice job with the super-agenda! I'll have to go find out more about it. – NickD Jul 18 at 15:49
  • I would suggest you rewrite the function to take an absolute date as argument and to calculate everything in terms of absolute dates, then convert to the final form at the very end. That should simplify the calculations and avoid unnecessary conversions. You can pass an absolute date to the function from your custom command by using (org-today) instead of the calendar function. Also, instead of calling the same function twice, you should store the result once and use it in both places. – NickD Jul 18 at 20:17

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.