I use MacOS built-in text replacement feature a ton, however, after I started using Firefox recently I quickly found out that it does not work. The feature is disabled in about:config
via setting named widget.macos.automatic.text_replacement
, but even if you enable it it only works for textarea
and not for widely used input
element. And there is no solution so far.
Well, there is a workaround by using TextFast extension that does exactly what it is supposed to do. It is a tiny open-source extension and quick look does not show any network activity except optional storing of the list to Firefox Account (disabled by default). And it has a JSON-based importing / exporting capability.
Luckily, all MacOS replacements can be saved to plist
file by selecting them all and dragging them into a folder. So in order to do that, open Downloads
folder, MacOS settings - Keyboard - Replacements, select them all and drag it to the folder. Then type this in a terminal:
cd $HOME/Downloads
cat >convert.py <<EOF
#!/usr/bin/python3
import plistlib
import json
out = []
with open(0, 'rb') as stdin:
for pair in plistlib.load(stdin):
n = {}
n["replace"] = pair["shortcut"]
n["with"] = pair["phrase"]
out.append(n)
print(json.dumps(out))
EOF
/usr/bin/python3 convert.py < "Text Substitutions.plist" > "Text Substitutions.json"
The first command changes the working directory to Downloads folder where text substitutions were dragged resulting into Text Substitutions.plist
file being created. The second command creates a short script that converts plist
into json
. And the third command executes the script creating a new file named Text Substitutions.json
.
Warning: Depending on your language, the file might be named differently. For example, in my Czech locale the file will be Textové záměny.plist
. Change the third command accordingly.
Now, open up the extension and use Import JSON feature to import your replacements. Done!
Here is my replacement list just as an example (and backup for myself). In case you are wondering, I use this feature to type English via my Czech keyboard layout which has the '
key hardly accessible via a dead-key combination:
[
{
"replace": "aintt",
"with": "ain't"
},
{
"replace": "arentt",
"with": "aren't"
},
{
"replace": "cantt",
"with": "can't"
},
{
"replace": "couldntt",
"with": "couldn't"
},
{
"replace": "couldvee",
"with": "could've"
},
{
"replace": "didntt",
"with": "didn't"
},
{
"replace": "doesntt",
"with": "doesn't"
},
{
"replace": "dontt",
"with": "don't"
},
{
"replace": "hadntt",
"with": "hadn't"
},
{
"replace": "hadvee",
"with": "had've"
},
{
"replace": "hasntt",
"with": "hasn't"
},
{
"replace": "haventt",
"with": "haven't"
},
{
"replace": "hedd",
"with": "he'd"
},
{
"replace": "helll",
"with": "he'll"
},
{
"replace": "heress",
"with": "here's"
},
{
"replace": "hess",
"with": "he's"
},
{
"replace": "howss",
"with": "how's"
},
{
"replace": "Idd",
"with": "I'd"
},
{
"replace": "Illl",
"with": "I'll"
},
{
"replace": "Imm",
"with": "I'm"
},
{
"replace": "isntt",
"with": "isn't"
},
{
"replace": "itdd",
"with": "it'd"
},
{
"replace": "itlll",
"with": "it'll"
},
{
"replace": "itss",
"with": "it's"
},
{
"replace": "Ivee",
"with": "I've"
},
{
"replace": "letss",
"with": "let's"
},
{
"replace": "njn",
"with": "No jo no."
},
{
"replace": "shedd",
"with": "she'd"
},
{
"replace": "shelll",
"with": "she'll"
},
{
"replace": "shess",
"with": "she's"
},
{
"replace": "shouldntt",
"with": "shouldn't"
},
{
"replace": "somebodyss",
"with": "somebody's"
},
{
"replace": "someoness",
"with": "someone's"
},
{
"replace": "somethingss",
"with": "something's"
},
{
"replace": "thatdd",
"with": "that'd"
},
{
"replace": "thatlll",
"with": "that'll"
},
{
"replace": "thatss",
"with": "that's"
},
{
"replace": "theydd",
"with": "they'd"
},
{
"replace": "theylll",
"with": "they'll"
},
{
"replace": "theyree",
"with": "they're"
},
{
"replace": "wasntt",
"with": "wasn't"
},
{
"replace": "welll",
"with": "we'll"
},
{
"replace": "weree",
"with": "we're"
},
{
"replace": "werentt",
"with": "weren't"
},
{
"replace": "whatss",
"with": "what's"
},
{
"replace": "wheress",
"with": "where's"
},
{
"replace": "whyss",
"with": "why's"
},
{
"replace": "youdd",
"with": "you'd"
},
{
"replace": "youlll",
"with": "you'll"
},
{
"replace": "youree",
"with": "you're"
},
{
"replace": "youvee",
"with": "you've"
}
]