14

I have a lot of custom keyboard shortcuts and will be migration Macs. I tested Migration Assistant and it did not seem to get these.

I read somewhere that they are stored in the individual application's plist files in the ~/Library/Application Support folder but even after copying a few of these folders over the shortcuts do not seem to follow.

How can I get all of the keyboard shortcuts migrated to a new mac?

screenshot-with-shadow.png

Glorfindel
  • 4,089
  • 8
  • 24
  • 37
cwd
  • 17,668
  • 42
  • 121
  • 159

2 Answers2

15

The shortcuts that can be changed from the Application Shortcuts tab are stored in ~/Library/Preferences/.GlobalPreferences.plist and in the property lists of applications in ~/Library/Preferences/*.plist and ~/Library/Containers/*/Data/Library/Preferences/*.plist.

$ defaults find NSUserKeyEquivalents
Found 1 keys in domain 'Apple Global Domain': {
    NSUserKeyEquivalents =     {
        "Actual Size" = "@0";
        "Automatic Fit" = "@9";
        "Automatically Resize" = "@9";
        "Browse All Versions..." = "^@v";
        "Decrease Indent Level" = "^\\Uf702";
        "Decrease Level" = "^\\Uf702";
        "Decrease Paragraph Indent" = "^\\Uf702";
        "Enter Full Screen" = "^@f";
        "Enter Full Screen Mode" = "^@f";
        "Exit Full Screen" = "^@f";
        "Exit Full Screen Mode" = "^@f";
        "Find Next" = "@g";
        "Find Previous" = "$@g";
        "Find and Replace..." = "~@f";
        "Full Screen" = "^@f";
        Fullscreen = "^@f";
        "Increase Indent Level" = "^\\Uf703";
        "Increase Level" = "^\\Uf703";
        "Increase Paragraph Indent" = "^\\Uf703";
        "Line Spacing..." = "~@l";
        Minimize = "\001";
        "Minimize All" = "\001";
        "Move Line Down" = "^\\Uf701";
        "Move Line Up" = "^\\Uf700";
        "Next Tab" = "~@\\Uf703";
        "Next Workspace" = "~@\\Uf703";
        "Normal Screen" = "^@f";
        "Original Size" = "@0";
        "Previous Tab" = "~@\\Uf702";
        "Previous Workspace" = "~@\\Uf702";
        "Remove Full Screen" = "^@f";
        Reveal = "$@r";
        "Select Next Tab" = "~@\\Uf703";
        "Select Next Tab View" = "~@\\Uf703";
        "Select Previous Tab" = "~@\\Uf702";
        "Select Previous Tab View" = "~@\\Uf702";
        "Shift Down" = "^\\Uf701";
        "Shift Left" = "^\\Uf702";
        "Shift Right" = "^\\Uf703";
        "Shift Up" = "^\\Uf700";
        "Show Next Tab" = "~@\\Uf703";
        "Show Previous Tab" = "~@\\Uf702";
        "Show in Finder" = "$@r";
        "Toggle Full Screen" = "^@f";
        "Use Selection for Find" = "@e";
        "Zoom Reset" = "@0";
        "Zoom to Fit" = "@9";
    };
}
Found 1 keys in domain 'com.panic.Transmit': {
    NSUserKeyEquivalents =     {
        "Hide Invisible Files" = "$@.";
        Refresh = "@r";
        "Show Invisible Files" = "$@.";
        "Synchronize..." = "$@y";
    };
}
Found 1 keys in domain 'net.sourceforge.skim-app.skim': {
    NSUserKeyEquivalents =     {
        Crop = "@k";
        "Single Page" = "$@1";
        "Single Page Continuous" = "$@0";
        "Two Pages" = "$@2";
    };
}
Found 1 keys in domain 'com.googlecode.iterm2': {
    NSUserKeyEquivalents =     {
        "Next Pane" = "@\\Uf703";
        "Open Autocomplete..." = "@;";
        "Previous Pane" = "@\\Uf702";
        "Select Pane Above" = "@\\Uf700";
        "Select Pane Below" = "@\\Uf701";
    };
}
Found 1 keys in domain 'net.notational.velocity': {
    NSUserKeyEquivalents =     {
        Bold = "\001";
        Delete = "$@d";
        Italic = "\001";
        "Plain Text Style" = "\001";
        Strikethrough = "\001";
    };
}
Found 1 keys in domain 'com.apple.Safari': {
    NSUserKeyEquivalents =     {
        "Mail Contents of This Page" = "\001";
        "Reopen All Windows from Last Session" = "~$@r";
        "Reopen Last Closed Window" = "~@r";
    };
}
Found 1 keys in domain 'com.hogbaysoftware.WriteRoom.mac': {
    NSUserKeyEquivalents =     {
        "Column 120" = "$@7";
        "Column 200" = "$@8";
        "Column 40" = "$@1";
        "Column 50" = "$@2";
        "Column 60" = "$@3";
        "Column 66" = "$@4";
        "Column 80" = "$@5";
        "Column 90" = "$@6";
        "Column Window Width" = "$@0";
        "Enter Full Screen" = "$@f";
        "Enter Full Screen Single" = "^@f";
        "Exit Full Screen" = "$@f";
        "Exit Full Screen Single" = "^@f";
    };
}

I actually use a shell script like this to configure the shortcuts:

defaults write -g NSUserKeyEquivalents '{
"Browse All Versions..." = "^@v";
"Minimize" = "\1";
"Minimize All" = "\1";
"Show Previous Tab" = "~@\Uf702";
"Show Next Tab" = "~@\Uf703";
}'

defaults write -app Safari NSUserKeyEquivalents '{
"Reopen Last Closed Window" = "~@r";
"Reopen All Windows from Last Session" = "~$@r";
"Mail Contents of This Page" = "\1";
}'

The shortcut strings use the same format as in DefaultKeyBinding.dict. You can remove a shortcut by assigning a menu item to \1. If you assign a menu item to nil, it is triggered when you press n in some applications like Audacity. If you assign a menu item to to \0, it is triggered when you press any key in Safari in 10.9.

Note that preferences are cached in Mavericks. Changes made with defaults are still applied after you just quit and reopen an application. But if you edit a plist directly or replace the plist, you also have to run killall cfprefsd or defaults read /path/to/plist.

Lri
  • 40,894
  • 7
  • 119
  • 157
13

Thanks to the existing answer, I've built a script which will save the shortcuts into a script to be run on other machines.

#!/bin/sh
# save-hotkeys.sh

DESTFILE=~/install-hotkeys.sh
echo '#!/bin/bash' > $DESTFILE

defaults find NSUserKeyEquivalents | sed -e "s/Found [0-9]* keys in domain '\\([^']*\\)':/defaults write \\1 NSUserKeyEquivalents '/" -e "s/    NSUserKeyEquivalents =     {//"  -e "s/};//" -e "s/}/}'/" >> $DESTFILE
echo killall cfprefsd >> $DESTFILE
chmod a+x $DESTFILE

Save this into a file called save-hotkeys.sh and execute it by running sh save-hotkeys.sh. On the remote machine, execute ./install-hotkeys.sh while in the same directory as the file. In my example, I save the file to dropbox so that it is synced to my other machines.

peterh
  • 2,553
  • 10
  • 31
  • 49
Alan Shutko
  • 4,168
  • 1
  • 19
  • 24
  • Hi Alan, that's great. How do run that script? Save it into a file? What extension should it be? Run it by double click the file? – angry kiwi Jul 23 '14 at 03:16
  • Added some explanation how to use it. – Alan Shutko Jul 23 '14 at 03:24
  • @ Alan Shutko, I got this error when I'm executing save-hotkeys:Af-MacBook-Pro:HD 2 af$ sh save-hotkeys.sh save-hotkeys.sh: line 5: /Users/Af/Dropbox/install-hotkeys.sh: No such file or directory – angry kiwi Jul 27 '14 at 04:55
  • Hi Alan, anyupdate? – angry kiwi Aug 09 '14 at 01:35
  • @runrunforest: Your shell script failed because you didn't have the `~/Dropbox` directory created. – dan May 02 '16 at 13:31
  • macOS 10.12 Sierra: The key `NSUserKeyEquivalents` contains the settings from `System Preferences > Keyboard > Shortcuts > App Shortcuts`. But how do I include the settings from `System Preferences > Keyboard > Shortcuts > Services` ? Those are no more within the domain `.GlobalPreferences.plist` aka `Apple Global Domain`. **In which domain and key are they stored now?** – porg Nov 28 '16 at 08:56
  • Background info: Now as of macOS 10.12.1 Sierra the issue is that the key bindings for Services get lost occasionally without any OS upgrades or Services upgrades! I guess the loss of the key bindings happens during system restarts or maybe even more frequently during sessions? Thus I intended to use the script as a backup/restore tool to the rescue, if necessary as a startup script, as I hate to do it manually again and again. But sadly the **Services key bindings** are not included, and those are the ones getting lost. The **App Shortcuts** had no issues so far. – porg Nov 28 '16 at 09:04
  • History: This script had worked fine when I set up a fresh OS X 10.9 for migrating my 10.6.8 settings. Recently I have upgraded from 10.9 to 10.12. Since post Steve Jobs Apple sucks in quality control, I seem to only upgrade every 2nd or 3rd major OS updates, as they contain too many bugs in the minor versions x.1.* and even x.2.* and many pro user features or customization break during upgrade, as i.e. this issue proofs, which costs me to much productivity, thus I skip 1-2 OS upgrades. – porg Nov 28 '16 at 09:05
  • `~/Library/Preferences/pbs.plist` is the storage location for Service settings in macOS 10.12 Sierra, containing the services' names and visibility state in the main menu and contextual menus and the user's key bindings. The man page for `pbs` says `pbs is an agent for the Services menu. It scans for and vends available Services, to populate the Services menu.` This plist contains a `key_equivalent` variable for each Service with a custom key binding. Just how do we add this correctly to your backup/restore script? – porg Nov 28 '16 at 09:55
  • This is freakin' awesome! Kudos! – Dan Nov 08 '17 at 18:22
  • Ran the script. Can't wait to run its product on my laptop at home! – hepcat72 Nov 01 '19 at 16:18
  • 1
    Doesn’t work for me on 10.15.2 Catalina, after executing the file, it reports: `Unexpected argument NSUserKeyEquivalents; leaving defaults unchanged.` – Siniša Šašić Jan 13 '20 at 11:01
  • 1
    @SinišaŠašić on Catalina (or any new MacOS to date) you need to add at least one new App Shortcut before the NSUserKeyEquivalents appears. I just tested this method on Catalina after adding one (I modified "Quit..." on Chrome) and it worked well. – Matt Pavelle Jun 03 '20 at 21:10
  • 1
    On Catalina, use "NSGlobalDomain" instead of "Apple Global Domain", then it works. – MrWatson Sep 25 '20 at 12:21
  • @MattPavelle I have already had a ton of shortcuts. Just in case you meant creating a new one atop of that, I made one for testing. Nothing changed, it doesn’t work. Furthermore, saving a file doesn’t work anymore, when I enter the command ```sh save-hotkeys.sh``` it doesn’t generate any file as it used to be the case before. – Siniša Šašić Oct 27 '20 at 13:10
  • @MrWatson I have no clue what you are talking about as in the script there’s no “NSGlobalDomain” mentioned; this is the code I used, that the author made: ``` #!/bin/sh # save-hotkeys.sh DESTFILE=~/install-hotkeys.sh echo '#!/bin/bash' > $DESTFILE defaults find NSUserKeyEquivalents | sed -e "s/Found [0-9]* keys in domain '\\([^']*\\)':/defaults write \\1 NSUserKeyEquivalents '/" -e "s/ NSUserKeyEquivalents = {//" -e "s/};//" -e "s/}/}'/" >> $DESTFILE echo killall cfprefsd >> $DESTFILE chmod a+x $DESTFILE ``` – Siniša Šašić Oct 27 '20 at 13:12