Skip to content

Instantly share code, notes, and snippets.

@croian
Last active May 5, 2024 15:26
Show Gist options
  • Save croian/29dcd6cdd8dad06a060206c6afdcaa7e to your computer and use it in GitHub Desktop.
Save croian/29dcd6cdd8dad06a060206c6afdcaa7e to your computer and use it in GitHub Desktop.
A Complete Guide to Customizing Mac Keyboard Shortcuts

A Complete Guide to Customizing Mac Keyboard Shortcuts

To help make Mac keyboard shortcuts more like Windows/Linux, and/or just customize them to your liking and boost your productivity.

The instructions here worked for me on macOS Ventura 13.4.1 (22F82) and with Karabiner-Elements (where applicable) version 14.12.0.

This is the standard version of the guide, meant to be easy to use/understand by non-advanced users, and explicit/complete in its instructions. For a more terse guide / reference see the condensed version.

A Note on Command and Control

macOS uses the command key where other OS's use the control key for the most common shortcuts (e.g. ctrl/cmd+c -> copy, ctrl/cmd+f -> find, etc.). Some might be tempted to try to remap basically every app's default shortcuts to use ctrl instead of cmd, but I think it is far easier to just make the mental switch that the cmd key is equivalent to Windows' ctrl, and Mac's ctrl is equivalent to Windows' win key.

That being said, I do think you should use the same physical key for cmd on Mac as you do for ctrl on Windows (and the same physical key for ctrl on Mac as for win on Windows), as that will make things a lot easier on your brain (black out the keys with a sticker or marker if the symbols make it confusing). MacOS makes it easy to do this -- see the next section on how.

Swapping command and control keys

Because mac uses command where other OS's use control for the most common shortcuts,

if you have a keyboard that you use on both Mac and Windows/Linux, or if the physical layout of your keyboard has the control key in a more ergonomic place than the command key,

then it may make sense for you to tell macOS to swap the two keys:

  1. Open the System Settings app
  2. Go to Keyboard
  3. Click Keyboard Shortcuts...
  4. Go to Modifier Keys
  5. Select the desired keyboard from the dropdown menu
  6. Map the Control (^) Key to ⌘ Command
  7. Map the Command (⌘) Key to ^ Control

Shortcuts configurable in Settings app

Some macOS shortcuts are configurable by:

  1. Open the System Settings app
  2. Go to Keyboard
  3. Click Keyboard Shortcuts...

E.g. on Windows, switching desktops is done by win+ctrl+leftArrow and win+ctrl+rightArrow, so if you want to make your Mac shortcut similar, in the keyboard shortcuts window:

  1. Click Mission Control
  2. Expand the > Mission Control item
  3. Double-click the shortcut on the right of the Move left a space and press cmd+ctrl+left
  4. Double-click the shortcut on the right of the Move right a space and press cmd+ctrl+right

Shortcuts configurable via DefaultKeyBinding.dict

Some macOS shortcuts -- those that deal with navigating, selecting or manipulating text -- are configurable via a more advanced method.

Example

Moving text cursors a word at a time is ctrl+left/right on Windows, and alt+left/right on Mac. To change this, do the following.

  1. Go to /Users/[your username]/Library in finder
  2. Create a new folder called KeyBindings
  3. Open textEdit (or some other text editor that will save your file in UTF-8 encoding)
  4. Enter the following text:
{
  "@\UF702" = moveWordLeft:;  // cmd-left
  "@\UF703" = moveWordRight:; // cmd-right
}
  1. Save the file somewhere (Library is probably hidden in the save dialog) as DefaultKeyBinding.dict
  2. Via finder, drop the file into the KeyBindings folder
  3. Restart any open apps where you want the remap to take effect

NOTE: Some apps have their own full or partial overrides of these shortcuts, so these remaps may not work everywhere (see Karabiner Complex Modifications for a solution). E.g. Webstorm has its own customizable shortcuts for these actions, and Slack will honor moveWord[Left/Right] remaps but not moveTo[Beginning/End]OfLine remaps.

Here is my full file as of now:

{
  "@\UF702"  = moveWordLeft:;                                // cmd-left
  "@\UF703"  = moveWordRight:;                               // cmd-right
  "@$\UF702" = moveWordLeftAndModifySelection:;              // cmd-shift-left
  "@$\UF703" = moveWordRightAndModifySelection:;             // cmd-shift-right
  "\UF729"   = moveToBeginningOfLine:;                       // home
  "\UF72B"   = moveToEndOfLine:;                             // end
  "$\UF729"  = moveToBeginningOfLineAndModifySelection:;     // shift-home
  "$\UF72B"  = moveToEndOfLineAndModifySelection:;           // shift-end
  "@\UF729"  = moveToBeginningOfDocument:;                   // cmd-home
  "@\UF72B"  = moveToEndOfDocument:;                         // cmd-end
  "$@\UF729" = moveToBeginningOfDocumentAndModifySelection:; // cmd-shift-home
  "$@\UF72B" = moveToEndOfDocumentAndModifySelection:;       // cmd-shift-end
  "@\U007F"  = deleteWordBackward:;                          // cmd-backspace
  "@\UF728"  = deleteWordForward:;                           // cmd-delete
}

There's a lot more you can do with this file/method. See these resources for more info:

Disabling alt+[letter] foreign/special characters

Doing this will free up your alt key for shortcuts:

  1. Open System Settings app
  2. Go to Keyboard
  3. Under the Text Input section, in the Input Sources subsection click the Edit... button
  4. Turn on Show Input menu in menu bar
  5. If Unicode Hex Input is not listed in the input sources on the left:
    1. Click the + in the lower left of the dialog
    2. In the language selection on the left, scroll all the way down and select Others
    3. In the list on the right select Unicode Hex Input
    4. Click the Add button
  6. In the system menu bar (upper-right), click the Input menu (probably says US) and select Unicode Hex Input

Simple key remaps

If you don't use a programmable, ortholinear, ergonomic, split, keyboard (like I do), you should! But if you don't, and you want to remap single keys (or mouse buttons) to other keys/buttons (e.g. swapping caps lock and tab), you can use Karabiner-Element's Simple Modifications feature. It's pretty self-explanatory when you see it.

E.g. if my keyboard doesn't have mouse capability in its firmware, I'll map keypad_enter to a key (in a firmware or layout editor, like https://usevia.app), then use Karabiner to map keypad_enter to button1 (left mouse button).

Complex and per-app remaps

Karabiner's Complex Modifications feature can give you even more capabilities.

NOTE: This app and the methods I've found for configuring remaps are quite strange and non-user-friendly. But if you carefully follow these steps and the tips here, you should have success.

Example

Because Slack does not honor moveToEndOfLine remaps, let's rectify that by doing the following:

  1. Open Karabiner-Elements app
  2. Copy the following to clipboard:
{
  "title": "Ian's rules",
  "rules": [
    {
      "description": "Slack Home/End",
      "manipulators": [
        {
          "type": "basic",
          "from": {
            "key_code": "home",
            "modifiers": { "optional": ["left_shift"] }
          },
          "conditions": [
            {
              "type": "frontmost_application_if",
              "bundle_identifiers": ["com.tinyspeck.slackmacgap"]
            }
          ],
          "to": [{
            "key_code": "left_arrow",
            "modifiers": ["left_command"]
          }]
        },
        {
          "type": "basic",
          "from": { 
            "key_code": "end",
            "modifiers": { "optional": ["left_shift"] }
          },
          "conditions": [
            {
              "type": "frontmost_application_if",
              "bundle_identifiers": [
                "com.tinyspeck.slackmacgap"
              ]
            }
          ],
          "to": [{
            "key_code": "right_arrow",
            "modifiers": ["left_command"]
          }]
        }
      ]
    }
  ]
}
  1. In your web browser, go to https://genesy.github.io/karabiner-complex-rules-generator/
  2. Paste the JSON into the lower text box on the right side of the webpage
  3. Click outside the text box (this will trigger the JSON to load)
  4. Click the Install! button -- this should open a dialog in the Karabiner app
  5. Click the Import button
  6. Click Enable next to the Slack Home/End rule, or click Enable All in the lower right of the Ian's rules section
  7. Home/End should go to the beginning/end of line in Slack now, and shift+Home/End should select to the beginning/end of line. Voilà!

Some notes:

  • I used left_command in the "to" entry's "modifers" array -- if this doesn't work for you, try using left_control. After remapping things in both the System Settings app and DefaultKeyBinding.dict, and not knowing exactly how individual apps interpret keys/remaps/actions, it can become quite confusing! When in doubt, swap cmd/ctrl and try again.
  • Karabiner will retain a section for every import you do (try importing again -- you will notice two "Ian's rules" sections -- like I said, some strange behavior by this app). This can become messy quite quickly, so I recommend deleting all but the current section each time you import.
    • Also, if you've modified a rule and are re-importing, be sure to delete the old one, or you will have duplicate/conflicting rules.
  • That editor site is quite difficult to use and has bugs, but it's the best I found when getting started. After I established a template to work from, I found that it's a lot easier/faster to just manually manipulate your json file and paste it in, than it is to use the editor. (Use source control and an editor/IDE with JSON support to make the process much safer/easier.)
  • Adding "optional" modifiers in the "from" entry is what allows Home/End to work as desired when shift is held.
  • To find the Bundle Identifier or File Path values used in the "conditions" for a given app, use the Karabiner EventViewer:
    1. Click the Karabiner status menu (right side of system menu bar)
    2. Click Launch EventViewer
    3. Click Frontmost Application (in left column)
    4. Switch to another app
  • To find a key_code, use the Main section of the EventViewer (see above bullet)

More resources on Karabiner

Direct app switching

This is not a remap of a native feature, but it's something I find so incredibly useful (especially on a small, single monitor) on both Windows (via AutoHotkey) and Mac, that I'll put it here.

To assign cmd+ctrl+s to Slack, import the following JSON into Karabiner:

{
  "title": "Ian's rules",
  "rules": [
    {
      "description": "App switcher/launchers",
      "manipulators": [
        {
          "type": "basic",
          "from": { "key_code": "s", "modifiers": { "mandatory": ["left_control", "left_command"] } },
          "to": [{ "shell_command": "open '/Applications/Slack.app'" } ]
        }
      ]
    }
  ]
}

...add a "manipulator" entry for each app you commonly use, and your productivity will instantly increase.

One last thing

One of the advantages of programmable, ergonomic keyboards is that you can make custom layers, often accessed by holding down a thumb key, so that you rarely, if ever, have to stray much from the home row.

A similar, if slightly less ergonomic, result can be achieved on other keyboards, including the Mac laptop keyboard, by using Karabiner's complex modifications.

I highly recommend using one or more modifier keys reachable with your right thumb (or your left thumb if you tend to use your right hand for modifier keys) as a layer-switching key, for example by mapping right_cmd+i/j/k/l as up/left/down/right arrows, and right_cmd+u/o as home/end.

This is especially useful if you work with code or a lot of text editing, and will save you much time and strain. Go all out, mapping your most commonly used keys and symbols to more convenient, logical locations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment