Daniel Liden

Blog / About Me / Photos / Notebooks / Notes /

Making headings for recurring tasks in org mode

This short post shows how to use the org-clone-subtree-with-time-shift command to make org headings for recurring tasks. I was recently trying to add a five-week class to my org agenda and I didn't want to manually create each heading and add or modify the timestamp. This approach made it very easy.

How it works

Suppose I have an org mode heading representing a scheduled event, like a class:

* Class
SCHEDULED: <2024-03-26 Tue>

Now suppose this class is scheduled weekly for the next five weeks. We don't necessarily want to manually copy the heading and manually update each timestamp (though, admittedly, it would only take a minute or two). This is where org-clone-subtree-with-time-shift comes in.

When we invoke this function with the cursor on the first heading, we will be prompted for (1) the number of clones to create and (2) the time shift we want to use. In this example, we specify 4 clones (for a total of 5 headings) and a +1w time shift, to shift each heading by one week.

* Class
SCHEDULED: <2024-03-26 Tue>
* Class
SCHEDULED: <2024-04-02 Tue>
* Class
SCHEDULED: <2024-04-09 Tue>
* Class
SCHEDULED: <2024-04-16 Tue>
* Class
SCHEDULED: <2024-04-23 Tue>

Limitations

In some cases, you may want to change the names of the headers somewhat (such as by adding a counter; class 1, class 2, etc.). There are many different approaches to handle this programmatically, but it's beyond the scope of this short post. In this case, it takes just a few seconds to add a class number to each heading manually.

Further reading

Most helpfully, here is the documenation from C-h f org-clone-subtree-with-time-shift:

org-clone-subtree-with-time-shift is an interactive Lisp closure in ‘org.el’.

It is bound to C-c C-x c.

(org-clone-subtree-with-time-shift N &optional SHIFT)

Clone the task (subtree) at point N times. The clones will be inserted as siblings.

In interactive use, the user will be prompted for the number of clones to be produced. If the entry has a timestamp, the user will also be prompted for a time shift, which may be a repeater as used in time stamps, for example ‘+3d’. To disable this, you can call the function with a universal prefix argument.

When a valid repeater is given and the entry contains any time stamps, the clones will become a sequence in time, with time stamps in the subtree shifted for each clone produced. If SHIFT is nil or the empty string, time stamps will be left alone. The ID property of the original subtree is removed.

In each clone, all the CLOCK entries will be removed. This prevents Org from considering that the clocked times overlap.

If the original subtree did contain time stamps with a repeater, the following will happen:

  • the repeater will be removed in each clone
  • an additional clone will be produced, with the current, unshifted date(s) in the entry.
  • the original entry will be placed after all the clones, with repeater intact.
  • the start days in the repeater in the original entry will be shifted to past the last clone.

In this way you can spell out a number of instances of a repeating task, and still retain the repeater to cover future instances of the task.

As described above, N+1 clones are produced when the original subtree has a repeater. Setting N to 0, then, can be used to remove the repeater from a subtree and create a shifted clone with the original repeater.

For more, you can also consult:

Date: 2024-03-25 Mon 00:00

Emacs 29.3 (Org mode 9.6.15)