Previously, I discussed adding weather forecasts and file attachments to the Things to-do app using some small Go programs I’ve written.
AppleScript JSON encoder - Provides a basic JSON encoding capability, to serialize strings, integers, lists and dictionaries. Automating the User Interface. AppleScript Basics. By Jerry Stratton. Copyright © 2011. Permission is granted to copy, distribute and/or modify this. AppleScriptHTML AppleScriptHTML converts AppleScript source code to clean HTML representing styles and formatting.
In this post, I’ll share some AppleScripts I use to implement additional features: OmniFocus-style deferred tasks, project templates that live in the Bear notes app, a global “find in Things” keyboard shortcut, and scripts to write your current Safari or Google Chrome tabs to a Things task.
OmniFocus has “deferred” tasks: tasks that aren’t actionable until a certain date. Things can schedule tasks for a future date, but there’s no way to tell it “I’m not necessarily going to do it on that date.” There are “Someday” tasks, which are not actionable, but you can’t tell Things a Someday task should become actionable on a certain date.
So, the requirements for this feature:
- The task is not in the Someday list
- The task isn’t seen as actionable in the Anytime list, until its defer date
- The task becomes actionable on its defer date, but doesn’t show up in the Today list
- The task shows up under its defer date in the Forecast view
I’ve implemented this with AppleScript and a launchd task which runs on my always-on Mac Mini. A high level overview:
- Create a Things tag for deferred tasks (I called mine “Deferred 💤”)
- Every night at 12:01am, tell Things to sync with Things Cloud, and then…
- Look for tasks in the Today list tagged with “Deferred 💤”
- Move those tasks out of the Today list, back to Anytime
I’m not 100% sure how this will work across timezones — when I’m traveling and my Mac Mini is not — but I’ve never been clear how Things handles sync and scheduled tasks across timezones anyway, and this is enough of a corner case that I feel like I can 🤷🏻♂️ it away for now.
This solution consists of an AppleScript and a Launch Agent which runs it nightly:
You should be able to adapt the launch agent
plist to your own paths pretty easily, and similarly customize the AppleScript if your “Deferred” tag is named differently.
As a side note, while writing this script I finally tried out Script Debugger, and I’m really impressed with it! It’s very, very good software.
Project Templates with Bear
I find it useful to store project templates in Bear, my preferred personal notes app, for things like reviewing my personal budget and yearly chores. This script (a text, Gist version is below) creates a new project in Things based on the currently-open note in Bear.
Download the best royalty free images from Shutterstock, including photos, vectors, and illustrations. Enjoy straightforward pricing and simple licensing. Contact shutterstock. Shutterstock Editorial Photos. Search over 40 million editorial stock photos and images covering news, sports and entertainment. Authentic stock photos and imagery by award-winning artists. Discover Bigstock. Stock photography, vectors, videos accessible at any budget.
Place the script in
~/Library/Scripts/Applications/Bear. This allows you to run it with FastScripts whenever Bear is open.
When you run the script, it’ll create a new project in Things based on the following rules:
- The title of the note is the name of the new project
- Every bulleted item becomes a task in the new project
- Lines without bullets become notes on whatever task they’re underneath
- Lines beginning with
;result in empty lines in the tasks’s note
- Empty lines are completely ignored
- Parsing/processing stops when a horizontal rule
---is encountered; this allows for footer matter relevant only in Bear
Applescript Html Object
It’s unfortunate that empty lines are completely ignored; this means you have to put a semicolon anywhere you want an empty line in a tasks’s note. This reflects the limits of my AppleScript programming skills.
If the macOS pasteboard contains something other than text, you’ll get an AppleScript error
-1700. I haven’t yet bothered to figure out how to fix this; to work around it, just copy any text to the pasteboard and re-run the script.
Browser Tabs to Things
I forget where I originally got these, but I have AppleScripts which add a Things task containing a list of the current Safari or Google Chrome window’s tabs. The Safari script is here; the Chrome one here. (Again, a Gist with text versions of the scripts is below.)
Applescript Html Mail
I actually don’t use Chrome any more; I’ve moved over to Firefox for everything I used to do with Chrome. But I haven’t yet gotten around to rewriting these for Firefox. As I understand, this will be somewhat cumbersome (but possible!) since Firefox doesn’t have very full-featured AppleScript support.
Applescript Html To Pdf
Like the project templates script, you’ll place these in
~/Library/Scripts/Applications/[Safari Google Chrome], and run them via FastScripts.
Global “Find in Things” shortcut
Finally, I have a script that opens a new Things window and then opens the Find interface within Things. Honestly, this one is annoyingly slow, but it’s still handy so I still use it a couple times a day.
Place this script in
~/Library/Scripts and use FastScripts to assign it a global keyboard shortcut of your choosing.
Through the power of AppleScript, macOS’s automation features, iCal feeds and email, I’ve now replicated all the OmniFocus features I missed in Things, and then some!
This is a prime demonstration of why I (still) love using macOS. If Apple ever removes AppleScript/automation from macOS, I’ll never forgive them.