Textexpander Disenchantment

Yes, I understand this, and why I continue to subscribe to TE. But couldn’t you make this same argument about most every software program we use?

If Hazel ever went to a subscription service, they could charge me a small fortune and the math would still make sense with all those automation rules I have running. Alfred and Keyboard Maestro too. This is probably the future of software, whether we like it or not.

You still get the time back whether you can monetize it or not. The question is about what that 40 seconds a day is worth to you. If someone values 40 seconds a day of free time at more than $3.33 per month it doesn’t matter whether they could make more money with that 40 seconds, Text Expander would still make sense for them.

Do you find Keyboard Maestro to be relatively on par with TextExpander as far as expansion features? Fillable fields, etc.?

Just curious, as I’ve been considering getting KM for other reasons and if it could largely replace TE I’d be very happy. :slight_smile:

Pretty sure you could set up equivalents in KM for everything that TE does, but a lot of the more advanced features will have a more challenging learning curve and take a considerably bigger upfront time investment (e.g. creating your own input forms if you need expansion with fill-ins).

The KM forum is great. Lots of friendly, helpful people, and lots of examples. Yes the learning curve is steeper than TE, but Peter Lewis and crew will get you up that curve quickly.

3 Likes

I still use the version of TextExpander before the subscription model and will continue to do so as long as it keeps working. I have no interest in paying for a subscription service on a program with such simple functionality. As others have mentioned already, there are a LOT of other solutions to text expansion these days.

I have an iMac at home, carry a MacBook Pro, and work as a developer 8+ hours a day on Windows. For interoperability, I use Breevy on Windows which shares my TextExpander shortcuts through Dropbox. Dropbox provides world class synching and I don’t need other vendors to provide this functionality. PhaseExpress also runs on Windows and can share TextExpander snippets.

I’m a developer and I don’t buy the “you should keep paying if the programs provides you value” argument. If all my software required a subscription, I could not afford to turn my devices on. That is just a model that does not scale for the end user. There is nothing wrong with paying a fair price for a useful piece of software and then continuing to use it. If the vendor can improve the software in a way that is significant for your use case, then you should pay for that upgrade. If due to operating system changes over time, the vendor has to modify their code and give you a new version to keep it operational, they you should also pay a modest cost for that upgrade. This is a bit of a gray area whether there is planned obsolescence or if the cost is modest (looking at you Paralles).

Smile as a company can’t write a simple utility like TextExpander and sit back on their laurels and expect the same people to keep paying them to keep their company lights on. As a company, they need to innovate and come up with new products that people will buy. With a lot of software, there is plenty of room for new features, but I think this utility is pretty much feature complete. Most home users don’t have a need for “team sharing”. What most software companies do is come out with an enterprise version of their software when then add features that are company based. That doesn’t prevent a home user from purchasing that version, but it doesn’t impose the ongoing cost on to the their home user base for those enterprise features.

I have written a lot of software for my employers that have saved them (and continue to save them) both time and money in their business. There is no expectation on either side that just because I’ve done that, that they will continue to pay my salary without requiring me to do any more work. It is the fact that I continue to do that in new ways that keeps me employed.

There seems to be a trend to internalize synching (at a no doubt large cost for the company) and then subscriptionize their software to generate a constant steam of income. iCloud has finally become a viable form of synching for applications and Dropbox has always been one. We don’t need a one off solution for each application.

15 Likes

Actually, fill-in forms were the very first text expansion macros I did in KM. It found it pretty straightfoward.

1 Like

Have to agree here. KM is more automator, while text expander is more expander of text :slight_smile:

Same for 1Password (for web-forms).

For completeness: LaunchBar has snippets capabilities too.

1 Like

Yes, same here. Like with anything there are Pros and Cons with Typinator but surprised it doesn’t get more airtime because it’s a solid App. In my use cases, I am findeing my need for TE or Typinator has significantly decreased as I extend Hazel usage, …

It is the future if we allow it. I pay for software I like and can afford. Typinator was my replacement when Smile uses a subscription.

1 Like

Asserting greater productivity is not at all fallacious in this instance.

First, in a practical sense, it is reasonable to say that those “40 seconds” saved are during the workday and in the workplace (notwithstanding obvious caveats and unforeseen circumstances). Therefore, the overwhelming odds are that the time someone has to react increases.

Also, if using the snippets improves accuracy (meaning, standardization, avoiding typos, etc.) then that is time saved editing that you haven’t even contemplated and would be hard to in fact measure because you can’t predict how many times, or even if, you will make an error by manually typing out whatever you’ve used TE for.

1 Like

I really think it comes down to exactly how the time is saved. I think @Wolfie is half right. The seconds saved here and there may or may not add up to meaningful productivity gains. It just depends on how that time is being saved.

For me, I use text expansion (formerly TE, now Alfred) in a number of contexts. One thing I do is often send a large number of nearly identical email messages. Without expansion, the fasted way would be to have a template file stored somewhere and copy and paste the contents. But this means locating the template, copy and pasting subject lines and message bodies, bouncing back and forth between files. Let’s say if I do that, the task might take me 30 minutes to complete.

With expansion, I don’t have to locate a template file (A one-time time-saver), and I don’t have to do any bounding between files and copying different components (saving me a small amount of time for each email). This might cut down the time it takes to about 25 minutes. The five minutes it saves me IS meaningful because instead of completing the task at 9:30, I’m done at 9:25 and I am legitimately starting my next task 5 minutes earlier.

Similarly, I use a lot of expansion while transcribing interviews. Often I use it for complicated or difficult to type words (Resource Recovery and Circular Economy Act; Recyclability; municipalities), as well as inserting boilerplate and things like “[carriage return][carriage return] Interviewer:” “[carriage return][carriage return] Respondent:” These shortcuts might allow me to run the audio I am transcribing 10% faster than if I didn’t have those shortcuts, which is roughly a 10% time saving. When we’re talking about a 10% savings on a task that might take 120 minutes, that’s not trivial. I am 10% more productive – if I were billing (at all!) on a per-transcript basis, I could do (approximately!) 10% more transcription because of the expansion, and thus, 10% more business, than without.

That said: I also use expansion to insert email signatures, components of my address, or my phone number, and a few other little things here and there for me. These save me seconds, or fractions of seconds, which accumulated over the course of the day may total some number of minutes, and certainly they are convenient! But they don’t likely add meaningfully to my productivity such that they could turn into extra dollars and cents.

So all this is to say, not all time saved through text expansion is equal, and I’d say some contributes more meaningfully to productivity/time savings than others.

4 Likes

Yeah, if you’re doing transcription it’s absolutely essential.

I hadn’t thought of it that way. Thanks. What additions can you put on. I hang in with TE frankly I find that though Peter Lewis recommends one uses TE rather than his own Keyboard Maestro, that I could manage with text expansions just on KM. I don’t have THAT many; I know some folk have hundreds and I don’t expect to reach that number ever. What should I do? Any suggestions?

I have never used TextExpander, so I don’t really know all it can do. I have some macros in Keyboard Maestro that pop up an input dialog to ask for some values and then use those values in the right place in the expanded text. They actually fill out the To:, CC:, Subject:, and body of the email and insert a link from the front-most page in Safari. So all I do is type my trigger, fill in the values, and just check to make sure the link actually works. Then I press send.

I have finally decided to transition my snippets from TE to Alfred’s snippet expansion.

It’s not so much that I am disenchanted with TE; I have been a subscriber since they went to the subscription model. It’s more that I am no longer really using the advanced capabilities of TE to any extent and so it’s just an unnecessary subscription for me, and moving to Alfred is just one less piece of software to take care of.

The majority of my TE snippets are simple text substitutions, which work well with Alfred’s snippet expansion. I don’t know how Alfred performs with large numbers of snippets, but I haven’t seen issues yet, having imported maybe 50 or so thus far.

I do have some TE snippets which utilize pop-ups for selection among several options, and I’ll be playing with Alfred’s snippet triggers in coming days to see how well I can reproduce this functionality. Hopefully this will work out well.

I also have a couple of very complex TE snippets that are based on executing python code for some very complex operations. I suspect I could port those to Alfred snippet triggers as well, but since I actually haven’t needed any of these in a while due to workflow changes, I’ll leave that on the back burner.

For anyone who is also thinking of making this transition, I will include below a python script I am using to transfer my snippets to Alfred. BEWARE that I threw this together quickly last night to automate my own transition. It has minimal if any error checking and recovery; I didn’t invest the time since I only need to use it once.

You run it from the command line in Terminal, using the command:
te2alfred Textexpanderfile prefix suffix

Textexpander file is a file exported from TE by using the function to save the contents of a group; control click on a group name to get the context menu to find this. Export each group to a separate file which you run the script on. (It works this way because of the way exporting works when you use the subscription version of TE, which is what I have).

prefix and suffix specify the prefix/suffix that Alfred should apply to each snippet in the group. If you look at Alfred’s snippets setup this should be clear. Note that TE also allows you to apply a prefix (but not suffix) to a group as well. For unclesr reasons, when you do the export from TE this information does not appear in the output file, so you need to supply this info on the command line, You can leave it blank (specify “” for each parameter to indicate an empty string) and add it in Alfred later if you want, but you DO have to put something on the command line even if blank strings. Again, quick and dirty as a run-once script for me.

The program’s output is a file with the same name as the TE group file, but the extension changes to .alfredsnippets. This is a zip file as required for import to Alfred. Double click it and Alfred will import your snippets.

Again, this is a quick script for my purposes, so I would suggest checking the group just created in Alfred to ensure your snippets are properly imported. Use at your own risk. The code is brief and you can see what it is doing easily enough.

This code also ONLY handles TE plaintext snippets (type 0). All other types are exported into individual files named with the group, snippet name, and UUID of that snippet, and the contents of the file is both an Alfred-format JSON snippet description and the XML from TE. I did this so things like my more complex TE snippets that run code could be saved and I could decide what to do with them later if I need them.

Note that TE snippets that contain substitutions, like inserting the clipboard, are handled by this program because they are just plaintext snippets. However, not everything that TE can include works in Alfred, like pop-ups and choose lists and the like, so those snippets will get imported into Alfred but won’t actually work. If you use that functionality a lot you probably want to stay with TE in the first place.

There is a variable called snippet_replacement_strings near the top of the code. This provides a listing of strings for string substitution in the snippet. There is one entry, which replaces %clipboard (the TE code for inserting the clipboard into the snippet expansion) with {clipboard}, the Alfred equivalent. You can add any other substitutions as parenthesized pairs that you might want. I don’t use a lot of stuff like dates and the like in my snippets, so I didn’t include that here; I’ll fix those snippets by hand since I only have a few of them.

Anyway, this is not intended as criticism of TE, which I have used for years and was OK with paying for on the subscription plan when it was useful for me. I just don’t need the functionality anymore and so I have decided to employ Alfred for the limited text replacement I need.

Sorry for the length of this posting. I hope someone finds it helpful!

Code:

#!/usr/bin/python

import plistlib
import sys
import os.path
import zipfile


output_location = os.path.expanduser('~/Desktop/Test')

snippet_replacement_strings = (
	('%clipboard', '{clipboard}'),
	)

plist_template = u'''<?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">
<dict>
	<key>snippetkeywordprefix</key>
	<string>{}</string>
	<key>snippetkeywordsuffix</key>
	<string>{}</string>
</dict>
</plist>
'''

snippet_template = u'''{{
  "alfredsnippet" : {{
	"snippet" : "{}",
	"uid" : "{}",
	"name" : "{}",
	"keyword" : "{}"
  }}
}}
'''


def fail(s):
	sys.stdout.write(s)
	sys.exit(1)


def replace_strings(t):
	for f, r in snippet_replacement_strings:
		t = t.replace(f, r)
	return t


def transform_snippet(s):
	name = s['abbreviation'] if s.label == '' else s.label
	filename = '{} [{}].json'.format(name, s['uuidString'])
	ts = snippet_template.format(
				replace_strings(s['plainText']),
				s['uuidString'],
				name,
				s['abbreviation']
				)
	return filename, ts


def main():

	args = sys.argv

	# Parse the arguments; any errors, just fail.
	try:
		te_file = args[1]
		prefix = args[2]
		suffix = args[3]
		output_filename = os.path.splitext(os.path.basename(te_file))[0]
	except:
		fail('usage: TE2Alfred <TEFile>.textexpander <prefix> <suffix>\n')

	# Get the plist file
	try:
		p = plistlib.readPlist(te_file)
	except:
		fail('Failed to read textexpander plist file.\n')

	# Get the snippets
	snippets = p['snippetsTE2']

	# Create the zip archive for the group
	zfile = zipfile.ZipFile(
		os.path.join(output_location, output_filename) + '.alfredsnippets', 
		'w')
	
	# Write the info.plist file to the zip archive
	zfile.writestr('info.plist', plist_template.format(prefix, suffix))

	# Write the snippets to the file
	for s in snippets:
		filename, alfred_snippet = transform_snippet(s)
		if s['snippetType'] == 0: 		# Only handle text substitutions now
			zfile.writestr(filename, alfred_snippet.encode("utf-8"))
		else:							# Just write this one to a file
			with open(os.path.join(
				output_location, '[' + output_filename + '] ' + filename), 'w') as f:
				f.write(alfred_snippet)
				f.write('\n')
				f.write(repr(s))
		

	# Close the archive to ensure proper cleanup
	zfile.close()


if __name__ == '__main__':
	main()
4 Likes

Here’s an existing alternative (Linked from https://www.alfredforum.com/topic/8883-import-textexpander-snippets-into-alfred-v3/)

http://alfred.danieldiekmeier.de/

But with a little work you can create more powerful list and script filters in Alfred that can do things that weren’t possible in TE as well as replicate existing functionality – see Does TextExpander subscription version offer any advantages? - #12 by BradG at the end