
A quick TextMate KeyBindings tip
I love the keyboard, and I love keyboard shortcuts. It’s one of the reasons TextMate and I get along so well. There’s one thing that bothers me any time I’m editing text (in any application), though: having to move my right hand all the way over to the arrow keys just to move forward a couple of characters, say, after an auto-paired set of parenthesis that I want to get out of.
I know, it’s stupid for two reasons: first, it’s just not that big a deal, and second, I could just use the Emacs keybindings (^F,^B,^P,^N, etc.). Well, to that I say “phooey” on both counts. It is a big deal; I’ve probably lost hours of my life to that motion. As to the latter, I didn’t grow up on Emacs, and those shortcuts have just never nestled into my muscle memory. In related news, I already have some of those keys bound elsewhere.
I used to use KeyRemap4Macbook to map control-j,i,l and m to the cursor keys, but haven’t installed it since my last clean wipe (just in case it was part of the reason I had to do the clean wipe to begin with). I missed that convenience, though, so after 15 minutes of Googling, here’s the answer…
Allan Odgaard, creator of TextMate, offers the beginning of the solution on the TextMate blog. I found a little more detailed information around the net, too. Basically, you can add or edit a file called DefaultKeyBinding.dict in ~/Library/KeyBindings/ to add the keystrokes to all Cocoa applications. Mine looks like this now:
{
"^j" = "moveBackward:";
"^l" = "moveForward:";
"^m" = "moveDown:";
"^i" = "moveUp:";
"^E" = "\"editInTextMate:\"";
}
The first part of each pair is the keystroke, and the second part is the action. To find a list of the available actions, I just looked at /System/Library/Frameworks/AppKit.framework/Resources/StandardKeyBinding.dict, which has all of the default OS X keybindings in it. You’ll need Property List Editor to view the file in its default state. To view the file in a text editor, you have to convert it to an XML (old school and plain text) plist. If you’re curious, copy the file to your Desktop and, in Terminal, run plutil -convert xml1 ~/Desktop/StandardKeyBinding.dict.
After editing DefaultKeyBinding.dict and restarting your Cocoa apps, your new keyboard shortcuts will be available. That’s when I found the next problem. TextMate has ^J mapped to “Reformat and Justify” under the Text menu. I never, ever use that command, so that was just annoying. I first tried to just override it in System Preferences->Keyboard->Application Shortcuts, but that didn’t do anything. Next I found a post on macosxhints that offered a Terminal (defaults) command for changing default Application shortcuts. For example:
defaults write com.macromates.textmate NSUserKeyEquivalents -dict-add "Reformat and Justify" "nil"
Guess what? That didn’t do it. TextMate was still pwning the ^J shortcut. Next stop, the Resources folder of the TextMate application. There I found KeyBindings.dict, where it was easy to locate the offending shortcut. I commented out the line (//) and restarted TextMate. Ta. Dum. My new keyboard shortcuts now function perfectly.
By the way, the reason I didn’t use “k” for down is I actually do regularly use the kill keybinding to delete to the end of the line (as well as ^a to move to beginning and ^e to the end). Also, you might skip mapping “m” to down, as “n” right next to it is already mapped to moveDown:, as mentioned while complaining about Emacs keybindings. I have them both mapped now, so I can have lazy fingers if I want to. Further, note that these keybindings will not work when selecting text; once you press the shift key, you’re in a whole new world. You’d have map those as well if you wanted that functionality.
I’m happy now, and so are my fingers. Have any other brilliant keybinding stories? I’d love to hear them.

I agree TextMate is better with emac style bindings, in theory. As you describe, there are three keyBinding files with possible consequence to TextMate’s function. On my computer they live in: /Users/Tim/Library/KeyBindings/DefaultKeyBinding.dict /Applications/TextMate.app/Contents/Resources/KeyBindings.dict ~/Library/Application\ Support/TextMate/KeyBindings.dict
According to your blog, the /Application…/KeyBindings.dict takes precedence over the ~/Library…/KeyBinding.dict file, though I was always under the impression that the user defined file had the final say (see http://www.hcs.harvard.edu/~jrus/Site/Cocoa%20Text%20System.html). Also, if the menus in TextMate define a key stroke short cut, none of these keyBinding files seem to carry any weight. To over-ride a menu defined quick key, one has to use the System Preferences > Keyboard menu. Another observation is that the nomenclature is inconsistent as the KeyBindings.dict file might list ^T to mean control + capital-T (require shift + t). But in the menu items ^T means control + T-key.
And defining: “~t” = “transposeWords:”; Does not seem to work in any cocoa apps though it does work in terminal.
Overall, this system stinks–too many sites keep eyes on. Too complicated to be of use to anyone but the most militant keybinding demanding folks.
Brett, thanks again. You always seem to be one step ahead on solving the needs that I’m just dimly becoming aware of. I did a Vim tutorial the other day and really liked the bindings but I also love TextMate and wasn’t ready to let go of that. This is really useful for getting me started on pimping TM. Thanks again!