Use Edna Instead of the Repeater Pattern

evergreen

I use org planning (schedule and deadline) system a lot.

Here, I’m mixing the method and the tool. I don’t like it (don’t confuse the tool and the method), but at least I am aware of it. So this makes sense if schedule means “I don’t want to see this before that date” and deadline means “whatever happens, this will be done before that date”. If you use other meanings, the following is irrelevant to you.

There are 3 repeaters .+, + and ++. Those repeater are great for simple active timestamps and fulfil a lot of my use case, but don’t work well when you have to orchestrate the planning that has a scheduling and a deadline that are correlated.

Those are the use case I have and the reasons why I encourage not to use + or ++ and prefer edna when dealing with both schedule and deadline. I still use + for cases where edna won’t help.

a task that you don’t need to think about for some time after completion: use .+

For tasks like “fill the cat’s bowl”, you know that your cat takes some time to empty its stock (say 1 week).

So whenever you filled the bowl, you have 1 week before you need to be reminded of it. You don’t want to starve the poor animal, so you want this to be done at most after 10 days.

* NEXT fill the cat's bowl
  DEADLINE: <2021-09-24 Fri .+10d> SCHEDULED: <2021-09-22 Wed .+1w>

a task that happens every period of time: use + and edna

Say that you want to fill the cat’s bowl only on Sundays. This is not a use case for deadline, but more for an active timestamp and a scheduling..

You might want to be seduced by the ++ repeater.

* NEXT fill the cat's bowl
  SCHEDULED: <2021-09-26 Sun ++1w>
  <2021-09-26 Sun ++1w>

The scheduling part means “don’t bother me about this before that date” and the active timestamp means “show me this in the things to be done that day”.

Beware that closing it several times in a row will make it slide in the future.

See how a few closing will now make it appears in 1 months?

* NEXT fill the cat's bowl
  SCHEDULED: <2021-10-17 Sun ++1w>
  :PROPERTIES:
  :LAST_REPEAT: [2021-09-22 Wed 10:34]
  :END:
  :LOGBOOK:
  - State "DONE"       [2021-09-22 Wed 10:34]
  - State "DONE"       [2021-09-22 Wed 10:34]
  - State "DONE"       [2021-09-22 Wed 10:34]
  - State "DONE"       [2021-09-22 Wed 10:34]
  - State "DONE"       [2021-09-22 Wed 10:34]
  - State "DONE"       [2021-09-22 Wed 10:34]
  :END:
  <2021-10-17 Sun ++1w>

To mitigate the sliding issue for the active timestamp, I use + instead of ++. It will still slide, but slower, because it won’t try to necessarily move into the future.

About the schedule time, edna makes sure it won’t slide.

* NEXT fill the cat's bowl
  SCHEDULED: <2021-09-26 Sun>
  :PROPERTIES:
  :TRIGGER:  self() todo!("NEXT") scheduled!("sun")
  :END:
  <2021-09-26 Sun +1w>

This at least makes sure the entry will be seen from next Sunday and won’t slide.

* NEXT fill the cat's bowl
  SCHEDULED: <2021-09-26 Sun>
  :PROPERTIES:
  :TRIGGER:  self() todo!("NEXT") scheduled!("sun")
  :LAST_REPEAT: [2021-09-23 Thu 09:17]
  :END:
  :LOGBOOK:
  - State "NEXT"       [2021-09-23 Thu 09:17]
  - State "DONE"       [2021-09-23 Thu 09:17]
  - State "DONE"       [2021-09-23 Thu 09:17]
  - State "NEXT"       [2021-09-23 Thu 09:17]
  - State "DONE"       [2021-09-23 Thu 09:17]
  - State "DONE"       [2021-09-23 Thu 09:17]
  - State "NEXT"       [2021-09-23 Thu 09:17]
  - State "DONE"       [2021-09-23 Thu 09:17]
  - State "DONE"       [2021-09-23 Thu 09:17]
  - State "NEXT"       [2021-09-23 Thu 09:17]
  - State "DONE"       [2021-09-23 Thu 09:17]
  - State "DONE"       [2021-09-23 Thu 09:17]
  :END:
  <2021-10-24 Sun +1w>

See how even though the active timestamp slid (I don’t have an answer to this issue yet), the scheduled remaining to be next Sunday.

The (small, but still) interest of using + instead of ++ arises when you update an old entry.

For instance, this one, 1 month in the past

* NEXT fill the cat's bowl
  SCHEDULED: <2021-08-22 Sun>
  :PROPERTIES:
  :TRIGGER:  self() todo!("NEXT") scheduled!("sun")
  :END:
  <2021-08-22 Sun +1w>

Will become this one after 4 closing.

* NEXT fill the cat's bowl
  SCHEDULED: <2021-09-26 Sun>
  :PROPERTIES:
  :TRIGGER:  self() todo!("NEXT") scheduled!("sun")
  :LAST_REPEAT: [2021-09-23 Thu 09:19]
  :END:
  :LOGBOOK:
  - State "NEXT"       [2021-09-23 Thu 09:19]
  - State "DONE"       [2021-09-23 Thu 09:19]
  - State "DONE"       [2021-09-23 Thu 09:19]
  - State "NEXT"       [2021-09-23 Thu 09:19]
  - State "DONE"       [2021-09-23 Thu 09:19]
  - State "DONE"       [2021-09-23 Thu 09:19]
  - State "NEXT"       [2021-09-23 Thu 09:19]
  - State "DONE"       [2021-09-23 Thu 09:19]
  - State "DONE"       [2021-09-23 Thu 09:19]
  - State "NEXT"       [2021-09-23 Thu 09:19]
  - State "DONE"       [2021-09-23 Thu 09:19]
  - State "DONE"       [2021-09-23 Thu 09:19]
  :END:
  <2021-09-19 Sun +1w>

The active timestamp is still in the past, so it will still appear in the calendar on next Sunday.

Consider the same one, with ++

* NEXT fill the cat's bowl
  SCHEDULED: <2021-09-26 Sun>
  :PROPERTIES:
  :TRIGGER:  self() todo!("NEXT") scheduled!("sun")
  :LAST_REPEAT: [2021-09-23 Thu 09:20]
  :END:
  :LOGBOOK:
  - State "NEXT"       [2021-09-23 Thu 09:20]
  - State "DONE"       [2021-09-23 Thu 09:20]
  - State "DONE"       [2021-09-23 Thu 09:20]
  - State "NEXT"       [2021-09-23 Thu 09:20]
  - State "DONE"       [2021-09-23 Thu 09:20]
  - State "DONE"       [2021-09-23 Thu 09:20]
  - State "NEXT"       [2021-09-23 Thu 09:20]
  - State "DONE"       [2021-09-23 Thu 09:20]
  - State "DONE"       [2021-09-23 Thu 09:20]
  - State "NEXT"       [2021-09-23 Thu 09:20]
  - State "DONE"       [2021-09-23 Thu 09:20]
  - State "DONE"       [2021-09-23 Thu 09:20]
  :END:
  <2021-10-17 Sun ++1w>

It slid much faster in the future.

a task whose action time span is periodic: use edna

You might consider that you want to fill the cat’s bowl between Friday and Sunday, every week.

The most tempting way to do this (I did this before knowing edna), is this one:

* NEXT fill the cat's bowl
  DEADLINE: <2021-09-26 Sun ++1w> SCHEDULED: <2021-09-24 Fri ++1w>

This sounds ok. And works well if you try it.

* NEXT fill the cat's bowl
  DEADLINE: <2021-10-03 Sun ++1w> SCHEDULED: <2021-10-01 Fri ++1w>
  :PROPERTIES:
  :LAST_REPEAT: [2021-09-22 Wed 10:43]
  :END:
  :LOGBOOK:
  - State "DONE"       [2021-09-22 Wed 10:43]
  - State "DONE"       [2021-09-22 Wed 10:43]
  :END:

But, due to the way ++ makes the date slide, you might prefer using edna.

You might be tempted to use the following code

* NEXT fill the cat's bowl
  DEADLINE: <2021-09-26 Sun> SCHEDULED: <2021-09-24 Fri>
  :PROPERTIES:
  :TRIGGER:  self() todo!("NEXT") deadline!("sun") scheduled!("fri")
  :END:

But this won’t move the deadline in case you do this on Saturday. In that case, the deadline will be move “tomorrow” and the schedule “next week”. It will look like this.

* NEXT fill the cat's bowl
  DEADLINE: <2021-09-26 Sun> SCHEDULED: <2021-10-01 Fri>
  :PROPERTIES:
  :TRIGGER:  self() todo!("NEXT") deadline!("sun") scheduled!("fri")
  :LAST_REPEAT: [2021-09-22 Wed 10:43]
  :END:
  :LOGBOOK:
  - State "DONE"       [2021-09-22 Wed 10:43]
  :END:

With a deadline date prior to the schedule date. It is a very good way to see the task when it is too late.

I prefer first moving the planning to a location slightly before the scheduled date and then offset it by the correct number of days

* NEXT fill the cat's bowl
  DEADLINE: <2021-09-26 Sun> SCHEDULED: <2021-09-24 Fri>
  :PROPERTIES:
  :TRIGGER:  self() todo!("NEXT") deadline!("thu") deadline!("+3d") scheduled!("thu") scheduled!("+1d")
  :END:

That way, this setup will make sure the planning will be put at the next wanted time.

It is important to put the first occurrence of deadline or scheduled before the wanted scheduled time. Because by definition, you won’t see the item before the scheduled time. That means that at the time you will move the task to DONE, you are sure you won’t be in between the schedule and the deadline time.

a repeating task for which the schedule time might temporarily change

Still considering the fill the cat’s bowl example,

* NEXT fill the cat's bowl
  DEADLINE: <2021-09-26 Sun ++1w> SCHEDULED: <2021-09-24 Fri ++1w>

Imagine you decide that this time you will want to see the task only on saturday, you want to simply change the schedule time with C-c C-s.

This result on the following task

* NEXT fill the cat's bowl
  DEADLINE: <2021-09-26 Sun ++1w> SCHEDULED: <2021-09-25 Sat ++1w>

For that time, it is what you wanted, but chances are that you did not realize that this will impact all the future schedules.

* NEXT fill the cat's bowl
  DEADLINE: <2022-01-16 Sun ++1w> SCHEDULED: <2022-01-15 Sat ++1w>
  :PROPERTIES:
  :LAST_REPEAT: [2022-01-14 Fri 09:20]
  :END:

See? You won’t see the task until next Saturday. The initial rule of seeing the task starting Friday is gone.

Here also, the edna setup won’t have such issue.

Provided you have the following setup.

* NEXT fill the cat's bowl
  DEADLINE: <2021-09-26 Sun> SCHEDULED: <2021-09-24 Fri>
  :PROPERTIES:
  :TRIGGER:  self() todo!("NEXT") deadline!("thu") deadline!("+3d") scheduled!("thu") scheduled!("+1d")
  :END:

And provided you switched the scheduled that time to Saturday.

* NEXT fill the cat's bowl
  SCHEDULED: <2022-01-08 Sat> DEADLINE: <2021-09-26 Sun>
  :PROPERTIES:
  :TRIGGER:  self() todo!("NEXT") deadline!("thu") deadline!("+3d") scheduled!("thu") scheduled!("+1d")
  :END:

Moving it to done gives the following result.

* NEXT fill the cat's bowl
  SCHEDULED: <2022-01-21 Fri> DEADLINE: <2022-01-23 Sun>
  :PROPERTIES:
  :TRIGGER:  self() todo!("NEXT") deadline!("thu") deadline!("+3d") scheduled!("thu") scheduled!("+1d")
  :END:

See how it came back to Friday?

Actually, this is not the only stuff I want to reset sometimes. I also used APPT_WARNTIME to indicate how much time I want to be warned before the task time. With edna, I can also use delete-property!("APPT_WARNTIME") or set-property!("APPT_WARNTIME", "whatever time works in general") to reset this value and avoid a temporary setting impact future occurrences.

impact on another repeated task

Let’s continue with the example of filling the cat’s bowl. Let’s assume that there is another repeated task of sanitizing the cat’s bowl. Let’s assume that it is done like once a month. And no matter when it is done, it will be needed between 4 and 5 weeks afterwards.

Therefore, with repeated tasks, it would look like this

* NEXT fill the cat's bowl
  DEADLINE: <2021-09-26 Sun ++1w> SCHEDULED: <2021-09-24 Fri ++1w>

* NEXT sanitize the cat's bowl
  DEADLINE: <2021-10-08 Fri .+4w> SCHEDULED: <2021-10-01 Fri .+5w>
  - [ ] empty the cat's bowl
  - [ ] sanitize it
  - [ ] fill it again

The “sanitize the cat’s bowl” task does not need edna, as the standard repeaters do the job pretty well. But doing it implies filling the bowl as well. Because they are not related, you have to manually trigger the latter one as done when the former is done.

With, edna, I would model this like this:

* NEXT fill the cat's bowl
  DEADLINE: <2021-09-26 Sun> SCHEDULED: <2021-09-24 Fri>
  :PROPERTIES:
  :TRIGGER:  self() todo!("NEXT") deadline!("thu") deadline!("+3d") scheduled!("thu") scheduled!("+1d")
  :ID:       someid
  :END:

* NEXT sanitize the cat's bowl
  DEADLINE: <2021-10-08 Fri .+4w> SCHEDULED: <2021-10-01 Fri .+5w>
  :TRIGGER:  ids("someid") todo!("DONE")
  :END:
  - [ ] empty the cat's bowl
  - [ ] sanitize it
  - [ ] fill it again

When sanitizing the cat’s bowl, you end up telling org-mode that the bowl has also been filled, which in turn updates the planning information. To my mind, this is perfect.

have repeated habits that do not repeat in the agendas

When you have a repeater in a task, this task appears at every location in your agenda. For habits, and gtd getting current phase, it is way too much.

Using edna allows to see only the next iteration and avoid the noise of next occurrences.

conclusion

With + repeater pattern, as the name suggests, you only deal with repetition of the task.

Often, what you want (at least what I want) is not to indicate a repetition pattern but make sure that a repeating task will have a correct planning in the future. This is exactly what edna provides.

You don’t say anymore “increment that time value by X”, but “when it is done, the next time I want it to be planned will be Y”. This gives you way more control over the automation of the planning and (to me), makes org-mode really a trusted system (at least, as far as repeated task are concerned).