Some of the .plist
files I have on my system no longer appear to be editable XML files. But the command-line tool PlistBuddy
which you mentioned in the question can help manage these files, too.
I found a couple of tutorials for how to use it:
Just to be on the safe side, I copied my .GlobalPreferences.plist
before attempting to modify it.
This tool has an interactive mode. The following demonstrates a brief session - the lines with Command:
are the prompts from PlistBuddy, and the rest of that line is a command I typed in.
bash:tripleee$ /usr/libexec/PlistBuddy ~/Library/Preferences/.GlobalPreferences.plist
Command: Print :NSUserDictionaryReplacementItems
Array {
Dict {
replace = omw
with = On my way!
on = 1
}
Command: Add :NSUserDictionaryReplacementItems:1:replace string hello
Command: Add :NSUserDictionaryReplacementItems:1:with string goodbye
Command: Add :NSUserDictionaryReplacementItems:1:on integer 1
Command: Print :NSUserDictionaryReplacementItems
Array {
Dict {
replace = omw
with = On my way!
on = 1
}
Dict {
replace = hello
on = 1
with = goodbye
}
}
Command: exit
(The arrays are apparently zero-based; it will complain if you try to add
into a position that is already occupied, though you can use set
to change an existing value.)
You want to save
if you are happy with the results, otherwise just exit
and start over.
There is an import
command but my impression is that it only supports reading a string
into a single value. There is also a merge
command but it requires another .plist
file if I'm reading this correctly.
For a nontrivial import, I would create a simple shell script like this.
#!/bin/sh
/usr/libexec/PlistBuddy ~/Library/Preferences/.GlobalPreferences.plist <<\____done
delete :NSUserDictionaryReplacementItems
add :NSUserDictionaryReplacementItems array
add :NSUserDictionaryReplacementItems:0:replace string moo
add :NSUserDictionaryReplacementItems:0:with string bar
add :NSUserDictionaryReplacementItems:0:on integer 1
add :NSUserDictionaryReplacementItems:1:replace string baz
add :NSUserDictionaryReplacementItems:1:with string quux
add :NSUserDictionaryReplacementItems:1:on integer 1
add :NSUserDictionaryReplacementItems:2:replace string ick
add :NSUserDictionaryReplacementItems:2:with string don\'t
add :NSUserDictionaryReplacementItems:2:on integer 1
print :NSUserDictionaryReplacementItems
___done
Notice that any single quotes in the replacement string have to be backslash-escaped. Similarly, any literal backslashes will need to be doubled. I don't know if there are other special characters; I didn't stumble into any in my testing. The maximum of the replacement string appears to be 459 characters. (Weirdly, you get "Unrecognized Command" if you exceed this.)
Save this in a text file like /tmp/uplist
and run it with sh /tmp/uplist
. (You can't use TextEdit for this; remarkably, it does not actually support writing plain text files.)
Notice that there is no save
in this example; you will want to verify that it seems to do the correct thing before you replace the print
command on the last line with just save
and rerun the script.
When you run the script, it will unattractively print the Command:
prompt as many times as you have commands in the file. You might want to add a redirection >/dev/null
once you are satisfied that it works acceptably. Before you do that, check that there are no error messages mixed in there, especially if you have experimented with nontrivial changes.
Bewilderingly, the dict
data type is output in whatever order the system decides; don't be upset if the on
appears before the with
in individual Dict
entries.
macOS Force User Global Preferences Reread To Refresh GUI seems to indicate that the change will only take effect after a reboot.
I found that this preference now also seems to live in ~/Library/Containers/com.apple.Keyboard-Settings.extension/Data/tmp/Text Substitutions.plist
, which is a plain XML file, but so far, I'm not sure which is the master and which is some kind of mirror location.