I love Things as task manager. I have used many many different task managers in the past (Omnifocus, Taskpaper, Todoist, Rememberthemilk, Evernote), but it seems that Things sticks with me. I’m using it for more than a year now and that is longer than any other task manager before.
I’m also a GTD practitioner. It is a system that works for me. The only aspect that was always difficult for me to implement is the weekly review. But I think I found the problem and hopefully a solution.
The problem is that I have more to-dos in my system that I can handle during a weekly review. I would like to be able to pause the review process when necessary. In the ideal world, I can work on a review for say 10 minutes, pause it and resume later. Furthermore, I discovered that not all to-dos need a weekly review. Some I need to see next week, others in 4 weeks and maybe some in 3 months.
This means I need some kind of support from my task manager to manage the weekly review. I came up with the following process that consists of three stages: 1) start the weekly review, 2) do the weekly review, and 3) stop the weekly review. During stage 1, all to-dos that need a review get flagged (with the ‘ToReview’ tag). In stage 2 I will review every task with the ‘ToReview’ tag and give it a date for the next review and during stage 3 the ‘ToReview’ tag is removed from every to-do.
Inspired by Automators, I was wondering if I could build this functionality myself with a combination of Keyboard Maestro and AppleScript. Turns out, I can. So here is what I did.
The 3 stages are 3 separate AppleScripts.
AppleScript for Stage 2 - Update Next Review Date
tell application "Keyboard Maestro Engine" set aantalWeken to getvariable "NextReview" end tell set nextReviewDate to current date set nextReviewDate to nextReviewDate + (aantalWeken * weeks) tell application "Things3" set reviewString to (year of nextReviewDate) * 10000 + (month of nextReviewDate) * 100 + (day of nextReviewDate) as text set reviewString to "-NR" & text 3 thru 8 of reviewString set listOfToDos to selected to dos repeat with selectedToDo in listOfToDos set noteText to selectedToDo's notes as text if noteText contains "-NR" then set start to offset of "-NR" in noteText set oudeReview to text start thru (start + 8) of noteText set the noteText to my replace_chars(noteText, oudeReview, "") end if set noteText to noteText & reviewString set selectedToDo's notes to noteText set tagNames to tag names of selectedToDo set tagNames to my replace_chars(tagNames, "ToReview", "") set tag names of selectedToDo to tagNames end repeat end tell on replace_chars(this_text, search_string, replacement_string) set AppleScript's text item delimiters to the search_string set the item_list to every text item of this_text set AppleScript's text item delimiters to the replacement_string set this_text to the item_list as string set AppleScript's text item delimiters to "" return this_text end replace_chars
I’ll start with the script for stage 2 (doing the review). It’s the most complex one. I’ve created a keyboard maestro macro that asks for the number of weeks for the next review (for the selected tasks). It stores this number in a variable and starts the AppleScript.
The script then reads this variable and uses it to determine the next review date by taking the current date and adding the number of weeks to it. Then it switches to the Things application. It converts the next review date to a string with the following format: -NRYYMMDD (I use -NR prefix to make it easier to recognize it between all other information in the notes field). In the next step the script stores the selected to-dos in a list and loops through this list. For every selected to do, it checks if the note of the to-do already contains a string that starts with -NR and if so it replaces this string with the new review date. If there is no -NR string than the new review date is added at the end of the to-do’s note. Finally the script deletes the ‘ToReview’ tag from the to-do. By using the selected to-dos it is possible to give a whole bunch of tasks the same next review date with a single keystroke.
AppleScript for Stage 1 - Start Review
display dialog "When is the next review" default answer "yymmdd" set nextReview to text returned of result tell application "Things3" repeat with toDo in to dos if toDo's status is not equal to "completed" then set notesText to (the toDo's notes as text) if notesText contains "-NR" then set start to offset of "-NR" in notesText set reviewDate to text (start + 3) through (start + 8) of notesText if reviewDate ≤ nextReview then set tagNames to tag names of toDo set tagNames to tagNames & ",ToReview" set tag names of toDo to tagNames end if else set tagNames to tag names of toDo set tagNames to tagNames & ",ToReview" set tag names of toDo to tagNames end if end if end repeat end tell
The AppleScript for stage 1 starts the review process. It first displays a dialog and asks the user for a date for the next review. Then it checks for every open to-do in Things if it has a review date and if it is before the next review. If so it will flag the the to-do with the ‘ToReview’ tag. If a to-do has no next review date (meaning it has never been reviewed before) it will get the ‘ToReview’ tag by default.
When this script has run I can search in Things for all tasks with the tag ‘ToReview’ and Things will give me a nice list that contains all the tasks that need reviewing.
AppleScript for Stage 3 - Stop Review
tell application "Things3" set aTag to tag "ToReview" delete aTag end tell
The last AppleScript for stage 3 (stopping the review) is very simple. It just deletes the tag ‘ToReview’. By deleting the tag itself, it is automatically deleted from all tasks.
If I want to resume my review I just restart the script for stage 1 and it will immediately give me a list of tasks that need reviewing.
Some final thougths. I’ve used two different methods to get input from the user 1) via a dialog triggered by Keyboard Maestro, and 2) via a dialog triggered by AppleScript itself. There is no special reason for this, I was just experimenting.
You do not need Keyboard Maestro to get this to work. You can also bind the different AppleScripts to short-cuts via the system preferences.
This was my very first experiment with AppleScript. Love to see in the comments how the script could be improved. Hope it will give some inspiration for your own experiments.