I have my tweaked version of the DefaultKeyBinding.dict on github
Mac OS X Key Bindings
I recently wanted to change some key bindings on Mac OS X. After spending a lot of time searching I found the information that I needed. However, the information was spread across several different sites. This article aims to collect all of the information that I found in a single document.
Mac OS X allows for some powerful control over key bindings. The method I describe below allows you to modify the key binding behavior for every program that uses the standard Cocoa AppKit text edit objects.
The default key bindings are stored in:
The non-XML file format is basically key / action pairs:
A list of the most common non-printable key codes is shown below. A complete list can be found in the NSEvent.h header file.
TextMate Blog - Key bindings for switchers
Apple Documentation - Text Defaults And Bindings
Apple Documentation - NSResponder supported actions
Mac OS X allows for some powerful control over key bindings. The method I describe below allows you to modify the key binding behavior for every program that uses the standard Cocoa AppKit text edit objects.
The default key bindings are stored in:
/System/Library/Frameworks/AppKit.framework/Resources/StandardKeyBinding.dictUnfortunately, this file is XML and is very painful to read. You shouldn’t touch this file anyway, and you should make your modifications by creating the file:
/Users/USERNAME/Library/KeyBindings/DefaultKeyBinding.dictwhere USERNAME is the name of your user account. If the KeyBindings directory doesn’t exist then you should create it. Note that the file name differs between the system default (StandardKeyBinding.dict) and the user override (DefaultKeyBinding.dict).
The non-XML file format is basically key / action pairs:
/* ~/Library/KeyBindings/DefaultKeyBinding.dict */
{
"KEY1" = "ACTION1"; /* Bind KEY1 to ACTION1 */
"KEY2" = "ACTION2"; /* Bind KEY2 to ACTION2 */
...
}
An example is shown below:/* ~/Library/KeyBindings/DefaultKeyBinding.dict */
{
"^f" = "moveWordForward:"; /* Ctrl-f = next word */
"^b" = "moveWordBackward:"; /* Ctrl-b = previous word */
"^v" = "pageUp:"; /* Ctrl-v = page up */
"\UF729" = "moveToBeginningOfLine:"; /* Home = start of line */
"^\UF729" = "moveToBeginningOfDocument:"; /* Ctrl-Home = start of doc */
}
A key is defined either as a printable key character (e.g., “a”), or a non-printable key character in either octal (e.g, “\177″ for delete) or Unicode (e.g., “\UF700″ for up arrow) encoding. The key can be preceded by one or more key ‘modifiers’:Key Modifiers ^ : Ctrl $ : Shift ~ : Option (Alt) @ : Command (Apple) # : Numeric KeypadFor example, Control-Shift-Home would be “^$\UF729″, and Command-a would be “@a”. I’ve had some issues with the ordering of these key modifiers on OS X 10.5 Leopard. For example, “$^\UF703″ (Ctrl-Shift Right Arrow) doesn’t work, but “^$\UF703″ does. If you are combining multiple modifiers and it doesn’t work, try reordering them.
A list of the most common non-printable key codes is shown below. A complete list can be found in the NSEvent.h header file.
Non-Printable Key Codes Up Arrow: \UF700 Backspace: \U0008 F1: \UF704 Down Arrow: \UF701 Tab: \U0009 F2: \UF705 Left Arrow: \UF702 Escape: \U001B F3: \UF706 Right Arrow: \UF703 Enter: \U000A ... Insert: \UF727 Page Up: \UF72C Delete: \UF728 Page Down: \UF72D Home: \UF729 Print Screen: \UF72E End: \UF72B Scroll Lock: \UF72F Break: \UF732 Pause: \UF730 SysReq: \UF731 Menu: \UF735 Help: \UF746An action is simply a specific string denoting the action. A list of the most common supported actions is shown below. Note the colon at the end of each action. This is required.
Supported Actions alignCenter: newDocument: alignJustified: openDocument: alignLeft: orderBack: alignRight: orderFront: breakUndoCoalescing orderFrontLinkPanel: cancelOperation: orderFrontListPanel: capitalizeWord: orderFrontSpacingPanel: center orderFrontTablePanel: centerSelectionInVisibleArea: outline: changeCaseOfLetter: pageDown: checkSpelling: pageUp: clearRecentDocuments: paste: complete: pasteAsPlainText: copy: pasteAsRichText: copyFont: pasteFont: copyRuler: pasteRuler: cut: performClose: delete: performMiniaturize: deleteBackward: performZoom: deleteBackwardByDecomposingPreviousCharacter: printDocument: deleteForward: raiseBaseline: deleteToBeginningOfLine: revertDocumentToSaved: deleteToBeginningOfParagraph: runPageLayout: deleteToEndOfLine: saveAllDocuments: deleteToEndOfParagraph: saveDocument: deleteToMark: saveDocumentAs: deleteWordBackward: saveDocumentTo: deleteWordForward: scrollLineDown: hide: scrollLineUp: ignoreSpelling: scrollPageDown: indent: scrollPageUp: insertBacktab: selectAll: insertContainerBreak: selectLine: insertLineBreak: selectParagraph: insertNewline: selectToMark: insertNewlineIgnoringFieldEditor: selectWord: insertParagraphSeparator: setMark: insertTab: showContextHelp: insertTabIgnoringFieldEditor: showGuessPanel: insertText: startSpeaking: loosenKerning: stopSpeaking: lowerBaseline: subscript: lowercaseWord: superscript: moveBackward: swapWithMark: moveBackwardAndModifySelection: terminate: moveDown: tightenKerning: moveDownAndModifySelection: toggleBaseWritingDirection: moveForward: toggleContinuousSpellChecking: moveForwardAndModifySelection: toggleRuler: moveLeft: transpose: moveLeftAndModifySelection: transposeWords: moveRight: turnOffKerning: moveRightAndModifySelection: turnOffLigatures: moveToBeginningOfDocument: underline: moveToBeginningOfDocumentAndModifySelection: unscript: moveToBeginningOfLine: uppercaseWord: moveToBeginningOfLineAndModifySelection: useAllLigatures: moveToBeginningOfParagraph: useStandardKerning: moveToEndOfDocument: useStandardLigatures: moveToEndOfDocumentAndModifySelection: yank: moveToEndOfLineAndModifySelection: moveToEndOfLine: moveToEndOfParagraph: moveUp: moveUpAndModifySelection: moveWordBackward: moveWordBackwardAndModifySelection: moveWordForward: moveWordForwardAndModifySelection: moveWordLeft: moveWordLeftAndModifySelection: moveWordRight: moveWordRightAndModifySelection:There are two other variants of entries that allow you to do multi-key bindings and to bind a key to a sequence of actions.
/* ~/Library/KeyBindings/DefaultKeyBinding.dict */
{
/* Bind KEY1 to ACTION1 and ACTION2 */
"KEY1" = ("ACTION1", "ACTION2", ...);
/* Multi-key bindings */
"KEY1" = {
/* Bind KEY1 followed by KEY2 to ACTION1 */
"KEY2" = "ACTION1";
/* Bind KEY1 followed by KEY3 to ACTION2 */
"KEY3" = "ACTION2";
...
};
...
}
An example is shown below:/* ~/Library/KeyBindings/DefaultKeyBinding.dict */
{
/* An example of binding a sequence of actions to a single key.
Bind Control-Shift-Home to select the region from the cursor to the
beginning of the line. Windows-style Control-Shift-Home. */
"$\UF729" = ("setMark:","moveToBeginningOfLine:","selectToMark:");
/* An example of binding a sequence of keys to an action.
Bind Control-x Control-s to save. Emacs style C-x C-s. */
"^x" = { "^s" = "save:"; }
}
Examples
An example key binding file for partial Windows emulation./* ~/Library/KeyBindings/DefaultKeyBinding.dict */
{
"^\010" = "deleteWordBackward:";
"\UF729" = "moveToBeginningOfLine:";
"^\UF729" = "moveToBeginningOfDocument:";
"$\UF729" = "moveToBeginningOfLineAndModifySelection:";
"^$\UF729" = "moveToBeginningOfDocumentAndModifySelection:";
"\UF72B" = "moveToEndOfLine:";
"^\UF72B" = "moveToEndOfDocument:";
"$\UF72B" = "moveToEndOfLineAndModifySelection:";
"^$\UF72B" = "moveToEndOfDocumentAndModifySelection:";
"^\UF702" = "moveWordLeft:";
"^\UF703" = "moveWordRight:";
"\UF72C" = "pageUp:";
"\UF72D" = "pageDown:";
"^z" = "undo:";
"$\UF728" = "cut:";
"$\UF746" = "paste:";
"^\UF746" = "copy:";
"$\UF700" = "moveUpAndModifySelection:";
"$\UF701" = "moveDownAndModifySelection:";
"$\UF702" = "moveLeftAndModifySelection:";
"$\UF703" = "moveRightAndModifySelection:";
"^$\UF702" = "moveWordLeftAndModifySelection:";
"^$\UF703" = "moveWordRightAndModifySelection:";
}
An example key binding file for partial Emacs emulation./* ~/Library/KeyBindings/DefaultKeyBinding.dict */
/* The original bindings are from Mike Ferris of lorax.com as shipped
* with his TextExtras package. They were further modified by Mishka Gorodnitzky
* (misaka@pobox.com), Patrick Linskey, and Llew Mason.
*/
{
"~f" = "moveWordForward:"; /* M-f */
"~b" = "moveWordBackward:"; /* M-b */
"~<" = "moveToBeginningOfDocument:"; /* M-< */
"~>" = "moveToEndOfDocument:"; /* M-> */
"~v" = "pageUp:"; /* M-v */
"^v" = "pageDown:"; /* C-v */
"~d" = "deleteWordForward:"; /* M-d */
"~^h" = "deleteWordBackward:"; /* M-C-h */
"~\010" = "deleteWordBackward:"; /* M-backspace */
"~\177" = "deleteWordBackward:"; /* M-delete */
"~\UF728" = "deleteWordForward:"; /* delete */
"\UF729" = "moveToBeginningOfDocument:"; /* home */
"\UF72B" = "moveToEndOfDocument:"; /* end */
"@\UF729" = "moveToBeginningOfParagraph:"; /* A-home */
"@\UF72B" = "moveToEndOfParagraph:"; /* A-end */
"@\UF700" = "moveToBeginningOfDocument:"; /* A-up */
"@\UF701" = "moveToEndOfDocument:"; /* A-down */
"^\UF700" = "pageUp:"; /* C-up */
"^\UF701" = "pageDown:"; /* C-down */
"\UF72C" = "pageUp:"; /* page-up */
"\UF72D" = "pageDown:"; /* page-down */
"^/" = "undo:"; /* C-/ */
"~c" = "capitalizeWord:"; /* M-c */
"~u" = "uppercaseWord:"; /* M-u */
"~l" = "lowercaseWord:"; /* M-l */
"^t" = "transpose:"; /* C-t */
"~t" = "transposeWords:"; /* M-t */
"~/" = "complete:"; /* M-/ */
"^g" = "_cancelKey:"; /* C-g */
"^a" = "moveToBeginningOfLine:"; /* C-a */
"^e" = "moveToEndOfLine:"; /* C-e */
"^x" = {
"^x" = "swapWithMark:"; /* C-x C-x */
"^m" = "selectToMark:"; /* C-x C-m */
"^s" = "save:"; /* C-x C-s */
"^w" = "saveAs:"; /* C-x C-w */
"k" = "performClose:"; /* C-x C-k */
};
/* Mark-point stuff (Emacs-style mark and point bindings are
* implemented but not bound by default. In the text system the
* mark and point are ranges, not just locations. The "point" is
* the selected range.)
*/
"^@" = "setMark:"; /* C-@ */
"^ " = "setMark:"; /* C-space */
"^w" = "deleteToMark:"; /* C-w */
/* Mac Style F1-F5 bindings */
"\UF704" = "undo:"; /* F1 */
"\UF705" = "cut:"; /* F2 */
"\UF706" = "copy:"; /* F3 */
"\UF707" = "paste:"; /* F4 */
"\UF708" = "_cancelKey:"; /* F5 */
}
Links
Customizing the Cocoa Text System by Jacob RusTextMate Blog - Key bindings for switchers
Apple Documentation - Text Defaults And Bindings
Apple Documentation - NSResponder supported actions



