"Import TextExpander Group" Macro

Updated 2016-04-20: v1.0.3 adds versioning comment/changelog, improved action titles, status menu trigger (shown when Finder is active), renamed root group

Like several others, I'm one of those looking for an alternative to TextExpander now that they've gone subscription-only (haven't been happy with any of the dedicated expansion apps, and I've always wanted to try Keyboard Maestro, so...).

However, I couldn't find an easy way to convert my TextExpander snippets to Keyboard Maestro expansions; so in the spirit of learning the app I wrote a macro! Many thanks to the generic Create Text Expansions macro, which was invaluable in providing hints on how to accomplish this.

Please note the following:

  • You must select one or more .textexpander files in the Finder before invoking this macro. Easiest way to generate them is to open TextExpander, right click a group, and choose "Save a Copy of Group..."
  • The macro will currently only import abbreviations that output plain text
  • The macro does not attempt to replace TextExpander variables/etc. with Keyboard Maestro ones, so you'll have to do that yourself after the fact
  • The macro uses "pasting" for snippets; I'm not 100% sure if this is the best option, but according to this post long snippets can be really slow if you use "typing" for insertion, so I defaulted to pasting
  • TextExpander does not appear to include information about which apps a group can expand in, so you'll have to set that by hand after importing, too

I've successfully imported all of my TextExpander snippets, and the basic macro seems to be working great! If you have a feature request or run into trouble, let me know and I will try to help. Enjoy!

Import TextExpander Group.kmmacros (10 KB)


Thank you for sharing. I’m sure this will be of help to many.

I swiitched from TextExpander to Typinator quite a while ago – so long ago that I don’t remember why. It can import TextExpander files.

I swiitched from TextExpander to Typinator quite a while ago – so long ago that I don’t remember why. It can import TextExpander files.

That’s great! However, a gentle reminder that this is not the place to recommend TextExpander alternatives. There’s plenty of that around the web, including in this very forum. This is the place for working to find ways to make migrating from TextExpander to Keyboard Maestro as painless and easy as possible.

I maybe a little thick but I can’t get this to work for me. Selected the file in finder but it throws this error…

/var/folders/rx/knkknmn94x196czt3qbfg28r0000gn/T/Keyboard-Maestro-Script-B55A449E-B50C-419B-AD88-90164FE68AB0:126:144: execution error: Keyboard Maestro got an error: a kmmacros file or XML must be supplied (-1)

I also changed the selection to a specific path and selected the TextExpander file but it throws the same error.

Thanks! This worked great for me. Successfully imported all my TextExpander snippets!

That wonderfully descriptive error means that the XML for importing to Keyboard Maestro was malformed somehow. This usually means that something has occurred that my script didn’t anticipate and caused the Python script to throw an error. You can check for what XML is getting fed to Keyboard Maestro by enabling the second-to-last “Display variable…” action and running the macro again with the same .textexpander file(s). It will still throw the error, but you’ll get a second little window with the XML in it, too. Please let me know what is being shown there and we’ll go from there to find the problem and fix it!

Glad to hear!

Thanks for replying to me.
The error message is…

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">

Traceback (most recent call last):
  File "/var/folders/rx/knkknmn94x196czt3qbfg28r0000gn/T/Keyboard-Maestro-Script-0C99D91F-FE28-4A60-B59A-B3CA4D33A727", line 12, in <module>
    teDict = plistlib.readPlist(path)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plistlib.py", line 78, in readPlist
    rootObject = p.parse(pathOrFile)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plistlib.py", line 406, in parse
xml.parsers.expat.ExpatError: not well-formed (invalid token): line 41, column 0

It is likely that the XML processing of one or more parts of the process is very naive. Probably you have some character in there that is confusing the conversion (characters like < > " & are the most likely culprits, but other non-ASCII characters might be the issue too, and indeed it could be a character encoding problem).

Try editing your export file with BBEdit and looking for either weird characters or character encoding issues.

This means there’s a character in the very first index of line 41 in your .textexpander file that Python’s built-in XML parser is unable to parse, which is preventing my macro from reading your Text Expander snippets at all. peternlewis’ recommendation to open the file up in your favorite text editor is a good one (Apple’s Text Edit should do the trick, if you don’t have one). It’s possible that Text Expander is not properly escaping snippets (or equally possible that Python’s XML parsing is more brittle than it should be).

If you need help locating the error and are comfortable sharing the .textexpander file, feel free to upload it (or just line 41) here and I’ll take a look.


I opened the file in BBEdit and spotted it right away. Once that was removed and saved everything imported.

Thanks for the help :grinning:

Just a quick note that I’ve updated the macro; it now defaults to having text expansions trigger only after a word break instead of after any character (which results in a lot fewer accidental expansions; this was the behavior I pretty much always used in TextExpander).


Thanks for maintaining your macro.

Hey Ian,

Please put some sort of versioning info in your macro to save yourself and everyone else confusion.

Best Regards,

Are there any common practices for doing this? I’m not aware of any built-in method for versioning macros, but am also a complete Keyboard Maestro newbie.

There is no built-in method for versioning.

For my entire career, I have used header comments to document version and last update, as well as other important stuff. But it can be as simple as Comment Action, where you just show the Ver# and Last Update in the name. Like this, and put it at the top of your macro.

I'm more anal about this than most, so I also put something like this at the top of my post when I make an update to it:

UPDATED: 2016-04-20 17:28 CT

  • briefly list the changes

Just give us some clue that you have made a change, and when you made it. :smile:

Hey Ian,

Nope. Please yourself, but try to make the versioning really obvious.

Here's the sort of thing I do:

I really wish the comment action would allow RTF content, so I could put a monospaced font in there. It's hard to create nicely aligned readable comments using a proportional font.

I have a comment saved to a named-clipboard, and I use a macro to paste it into the working macro with a keystroke.

It's also a good idea to give the macro file itself a version number.


Nice, I wasn’t aware that you could change the title of actions. Versioning comment is now a thing, along with a few minor improvements to the macro’s display in Keyboard Maestro (no functional changes).

Is there a way to upload .kmmacros files to the forum without needing to use the “share” button in-app? It doesn’t look like there’s any good way to set the specific file name without modifying the name of the macro itself using that method (which was what I’ve been doing until now).

A post was split to a new topic: Export Selected Macros

This script is genius. Many thanks.

I have a TON of TE snippets. We are talking thousands. Will I overload KM if I import them all? Any caveats?