11/30/13 21:52:36

Convert TextExpander Snippets to iOS/OS X Text Shortcuts

TextExpander Snippets to iOS/OS X Text Shortcuts

Here is something I’ve been working on for quite a while now. I first had the idea for this when I went to Vienna. I was annoyed that Apple still didn’t allow TextExpander to do what I love it to do. Three weeks ago it looked bad for TextExpander already, now, a couple of weeks later, it looks even worse.

Since Mavericks, Text Shortcuts (System Preferences → Keyboard → Text) sync with iOS devices. I started thinking how to automate adding new shortcuts by script. Scripting the UI is, obviously and technically, my least favorite option, but it’s what I ended up doing.

If you are interested in the technical difficulties that I had to overcome, which make this script work the way it does, read on. Otherwise head to the end to download.

How OS X Text Shortcuts Work

When a new Text Shortcut gets added in the System Preference pane Keyboard → Text, OS X does a couple of things.

First it saves a “receipt” of this addition/removal to ~/Library/Mobile Documents/com~apple~TextInput/ in there are a couple of folders. Most important are those with your username. Open that folder and you see UserDictionary with a subfolder. Select the ones with “~” in their name.

Every time you add or remove a new shortcut a zipped plist will be saved here, containing an Epoch timestamp, the shortcut and the phrase (as Apple calls expansions). Some other data is in the plist as well, but the important bits are the ones I just described.

The other important folder is in ~/Library/Dictionaries/CoreDataUbiquitySupport. This folder looks similar. It contains two folders, somewhere you will find a UserDictionary.db file. This is a SQLite database.

When a new shortcut gets added, a new row will be created here. Again Epoch timestamp, shortcut, and phrase are the important pieces.

What Does Not Work

My first guess was to add new “receipt” files to Mobile Documents. I was hoping that OS X would realize there’s a new file, read it and add it to OS X Text Shortcuts, and that this would also transfer new shortcuts to an iOS device. It does not.
Adding new files here with a similar structure does not update the System Preference pane Table View, nor does it make an iOS device recognize the addition.

I started tinkering with SQLite then. The SQLite database in Dictionaries is only used to feed the Table View displayed in System Preferences. Add new rows here with a similar structure, restart System Preferences, and you will see the new shortcut. Editing the database files does not trigger iCloud to sync shortcuts.

At this point I was pretty disappointed and took my least favorite route, UI scripting. I know it’s hacky, I know it’s dirty, I know all that, but scripting the UI lead to a working solution.
Maybe looking a bit more into Mobile Documents would eventually have resulted in a better solution. I weighed the time it would take me to figure this out against the time it takes me to make a first running version. I prefer things to be done.

How This Script Works

PLEASE READ THIS, IT IS IMPORTANT! ALL YOUR EXISTING SHORTCUTS WILL GO POOF!

  1. Open System Preferences → Keyboard → Text
  2. Click the Table View, select all, press backspace. This deletes all existing shortcuts and takes a moment or two.
  3. Turn off TextExpander text expansion. This is important. Otherwise when the script types the phrase, TextExpander would expand the abbreviation.
  4. It will then compile a list of all your TextExpander snippets.
  5. The script will then click +, type out the abbreviation, ⇥ to the next cell, paste the expansion from the clipboard, press return.
  6. After it has completed typing all shortcuts, TextExpander text expansion will be turned back on.

A few things to note:

  1. As the script automates the UI, just sit and watch. It takes about 4:40 minutes to type in about 300 snippets.
  2. The clipboard is used, because this way the expansion can have multiple lines.
  3. This script is smart enough not to process any dynamic snippets. Dynamic snippets use date calculations, Fill-Ins, and any script snippets.
  4. It takes a while for the list of snippets to be compiled. If AppleScript Editor says “Running…” at the bottom, the script is still running.
  5. If you hear an error beep you may have luck running the script again. Sorry this happens sometimes, I couldn’t figure out why.
  6. Set all snippet groups that you don’t want to be added in disallowedGroups. The name must match the snippet group’s name.

If you want to know how many snippets you have, comment out the part where the script starts adding all Text Shortcuts. There is a line

log "Count of abbreviationList: " & (count of abbreviationList)

After this insert (*, and *) way at the end.

Download

GitHub