Yep, I tried writing a similar script a little while ago, and AFAICT, completing a repeating task generates a new completed task, and the original task becomes the next instance.
I’ve found a way around this, though it’s not super pretty. It relies on an apparent relationship between the ids of the repeating and the new, completed task—namely, that the completed task’s id is the original task’s id with an appended .0
(or .1
, or .2
, or so on, if those ids have already been generated for earlier repeats of the task).
My script generates the next instance of a repeating task by marking the repeating task as complete, then uncompleting the completed task and removing its repeat rule. This lets you change something about today’s copy of a task, without changing what will happen on future iterations. The script is a bit primitive right now, but it goes like this:
const document = Application("OmniFocus").defaultDocument
const repeatingTask = document.documentWindows[0].content.selectedTrees.value()[0]
repeatingTask.markComplete()
const tasks = document.flattenedTasks
const isRepeatOfId = id => id.startsWith(repeatingTask.id())
const currentTask = tasks.byId(tasks.id().filter(isRepeatOfId).sort().slice(-1)[0])
currentTask.markIncomplete()
currentTask.repetitionRule = null
You could implement the Skip script similarly, by changing the end of it:
const document = Application("OmniFocus").defaultDocument
const repeatingTask = document.documentWindows[0].content.selectedTrees.value()[0]
repeatingTask.markComplete()
const tasks = document.flattenedTasks
const isRepeatOfId = id => id.startsWith(repeatingTask.id())
const currentTask = tasks.byId(tasks.id().filter(isRepeatOfId).sort().slice(-1)[0])
currentTask.delete()
Or, you could use the first version of the script (if you want the flexibility), and manually delete today’s copy after running it.
Note that the script doesn’t have any kind of guardrails right now; be sure you have a task selected (in the main pane), and that it’s a repeating task. It will work on projects, but only if they’re selected in the main pane. And it will only touch the first selected task.