Writing to NSUserDictionaryReplacementItems with defaults

defaultsterminal

The following command reads the NSUserDictionaryReplacementItems. The keys are called Text Shortcuts in OS X.

defaults read NSGlobalDomain NSUserDictionaryReplacementItems

I want to create new shortcuts using the defaults command, because plists in Mavericks are now cached (and for various other reasons). As you can see from the output of the command above, it lists other keys and values. How would I access the keys and values within the main NSUserDictionaryReplacementItems key? The man page for defaults doesn't say how (or if) that can be done.

Best Answer

Different ways to add a replacement:

defaults write -g NSUserDictionaryReplacementItems -array-add '{on=1;replace=a;with=b;}'

defaults write -g NSUserDictionaryReplacementItems -array-add '<dict><key>on</key><integer>1</integer><key>replace</key><string>a</string><key>with</key><string>b</string></dict>'

Different ways to replace the whole list:

defaults write -g NSUserDictionaryReplacementItems -array '{on=1;replace=a;with="b \"\\b";}' '{on=1;replace=c;with=d;}'

defaults write -g NSUserDictionaryReplacementItems '({on=1;replace=a;with="b \"\\b";},{on=1;replace=c;with=d;})'

defaults write -g NSUserDictionaryReplacementItems '<array><dict><key>on</key><integer>1</integer><key>replace</key><string>a</string><key>with</key><string>b "\b</string></dict><dict><key>on</key><integer>1</integer><key>replace</key><string>c</string><key>with</key><string>d</string></dict></array>'

Quit and reopen applications to apply changes.

Edit: the changes made with defaults are lost if you open the Text tab of the Keyboard preference pane. To prevent it, use a script like this:

date=$(date +%s)
while read -r replace with; do
  plist+="{on=1;replace=\"$replace\";with=\"$with\";},"
  sql+="INSERT INTO 'ZUSERDICTIONARYENTRY' VALUES($((++i)),1,1,0,0,0,0,$date,NULL,NULL,NULL,NULL,NULL,\"$with\",\"$replace\",NULL);"
done < <(sed 's/\\/\\\\/g;s/"/\\"/g' ~/replacements.txt)
sqlite3 ~/Library/Dictionaries/CoreDataUbiquitySupport/$USER~*/UserDictionary/local/store/UserDictionary.db "delete from ZUSERDICTIONARYENTRY;$sql"
defaults write -g NSUserDictionaryReplacementItems "(${plist%?})"

The replacements are saved to ~/Library/Dictionaries/CoreDataUbiquitySupport/$USER~*/UserDictionary/local/store/UserDictionary.db even if iCloud is disabled.