Simple recurring org-mode tasks!
This package extends org-mode and org-agenda with support for defining recurring tasks and easily scheduling them.
This package aims to be simple -- with the recommended configuration, you can
just press d
in the org-agenda to quickly reschedule a recurring chore.
Org-recur is incredibly good. It is so much more intuitive than the standard means to designate recurring tasks in org, and it easily integrated into my current org setup. What I was not expecting from org-recur, is how it cleaned up my org files, making them easier to manage and read. It placed all the important information on one line together, and eliminated time spent searching for deadlines.
~ anoduck
By adding some simple syntax to anywhere in the task heading you can control how often the task should recur.
Examples:
|+2|
: Recur every other day.|+w|
: Recur every week.|1|
: Recur on the first of every month.|Thu|
: Recur every Thursday.|Sun,Sat|
: Recur every Sunday and Saturday.*|Wkdy|
: Recur every weekday.*
[The syntax is mostly a superset of the syntax already accepted by
org-schedule
. Additional syntax, provided by org-recur, is marked by *.]
You can use the provided command org-recur-finish
to reschedule tasks based on
their recurrence syntax. With the point over a task, in either org-mode or
org-agenda, call org-recur-finish
and it will handle the task. The recommended
hotkey is C-c d
, and also d
in org-agenda.
If the task does not contain a recurrence syntax, the command will ignore it by
default. You can customize this to mark the task as DONE
and archive it.
The provided command org-recur-schedule-today
(recommended hotkey C-c 0
)
schedules any task to the current date.
Make sure you have set up MELPA and run:
M-x package-install RET org-recur RET
Or, if you have use-package:
(use-package org-recur
:demand t)
The following use-package
configuration:
- Enables
org-recur-mode
in org-mode files andorg-recur-agenda-mode
in org-agenda. - Sets the suggested keybindings (
C-c d
, as well asd
in org-agenda). - Enables
org-recur-finish
acting on headings without recurrence syntax, marking themDONE
and archiving them.
(use-package org-recur
:hook ((org-mode . org-recur-mode)
(org-agenda-mode . org-recur-agenda-mode))
:demand t
:config
(define-key org-recur-mode-map (kbd "C-c d") 'org-recur-finish)
;; Rebind the 'd' key in org-agenda (default: `org-agenda-day-view').
(define-key org-recur-agenda-mode-map (kbd "d") 'org-recur-finish)
(define-key org-recur-agenda-mode-map (kbd "C-c d") 'org-recur-finish)
(setq org-recur-finish-done t
org-recur-finish-archive t))
You can also check out my configuration (search "org-recur") which provides additional hotkeys that I find useful (like C-c 1
for scheduling to +1
, tomorrow).
Here are some org-mode settings that work well in conjunction with org-recur.
Refresh the org-agenda whenever a task is rescheduled:
;; Refresh org-agenda after rescheduling a task.
(defun org-agenda-refresh ()
"Refresh all `org-agenda' buffers."
(dolist (buffer (buffer-list))
(with-current-buffer buffer
(when (derived-mode-p 'org-agenda-mode)
(org-agenda-maybe-redo)))))
(defadvice org-schedule (after refresh-agenda activate)
"Refresh org-agenda."
(org-agenda-refresh))
Keep the task metadata clean:
;; Log time a task was set to DONE.
(setq org-log-done (quote time))
;; Don't log the time a task was rescheduled or redeadlined.
(setq org-log-redeadline nil)
(setq org-log-reschedule nil)
Prefer rescheduling to future dates and times:
(setq org-read-date-prefer-future 'time)
org-recur supports time of day. It looks something like this: |1 10:00, 15 12:00| headline
. It's a bit verbose, but you can specify different times of day for each date. If you don't want the verbosity you can move the time of day outside of org-recur: |1, 15| 10:00 headline
works just fine, and is what I have been doing. org-agenda will pick up the time in either scenario.
You can customize the org-recur-weekday-recurrence
variable to match your lifestyle. If a "weekday" (a day in which you work or study) for you includes Sunday, or excludes Wednesday, you can modify the variable accordingly.
It is possible to have todo states in a heading -- they are compatible with
org-recur
, though they are not necessary to have. If you wish to include a
todo state, it must appear first in the heading, or it will not be
picked up by org-mode. So, the correct format would look like this:
** TODO |wkdy| test
Note that org-recur
does not have this limitation; the recurrence syntax
(|wkdy|
) can appear anywhere in the heading.
org-recur
does not touch todo states, except when completing a one-off task
(when enabled). Apart from that, they need to be managed manually. i.e.
org-recur
does not try to guess how a todo state should change for recurring
tasks. This keeps the package simple and unopinionated.
org-recur doesn't allow for something like "first Wednesday of the month". It only supports org-schedule
syntax (which is its backend) as well as the ability to pick the soonest of several options. These unfortunately can't be combined for some more complicated recurrences.
For a possible alternative which allows for this, please see "Sexp diary entries" below and here for an example.
org-mode already supports "repeated tasks", but it has some shortcomings:
- Tasks need to have a TODO status set. I have a lot of recurring tasks and I don't want them all to be TODO.
- You can't see how often a task recurs from the org-agenda view, you only see the task's headline and not its
SCHEDULED
/DEADLINE
timestamps. - Repeated tasks require the
.+
syntax to shift the date based on today, which is what I almost always want. If I want to schedule a+2
task to tomorrow I can do that manually, but I still want it to be clear that the task should recur every two days.
org-recur is also simpler. I want to think as little as possible when I organize my time, helping keep my personal time management frictionless.
org-habit is similar to org-recur and has some interesting, albeit unnecessary features. The same drawbacks apply as above; in addition, org-recur is much simpler.
You can also get some features of org-recur using Diary-style sexp entries. For example, you can get the |1,15|
recurrence with SCHEDULED: <%%(diary-date t '(1 15) 2019)>
(see C-h f diary-date
).
The biggest shortcoming of this approach, it seems to me, is the complexity of it. You also can't see the timestamp from the org-agenda view.