Customize the Cocoa text binding system

Mar 21, '06 06:52:00AM

Contributed by: jacobolus

I just wrote a very detailed article about the Cocoa Text System, covering a whole lot of really cool stuff about how it works. I hope you all enjoy it! Anyway, I thought I'd distill three or four quick hints from the writeup into a general Cocoa text system hint for macosxhints. If any of this is unclear, please hop over to the article, which tries to be as explicit as possible, and explain things from the beginning.

Hint #0: Default keyboard shortcuts

I've made a list of all the default keyboard shortcuts in Cocoa text boxes.

Hint #1: Key bindings to emulate another environment

It is possible to create a special file, ~/Library -> KeyBindings -> DefaultKeyBinding.dict, which can modify the keyboard shortcuts in every Cocoa text field (which means most text fields in programs on OS X, though not Microsoft Word, or Firefox, or Adobe programs). This is a property list file which lists the actions to be performed with each of the desired shortcuts. It is possible, by modifying this file, to get Cocoa text fields to behave a bit more like Windows, or BBEdit (which has some excellent additions to standard Mac behavior, such as shift-delete for forward delete), or Emacs (the terminal-based editor that has more shortcuts than you can shake a stick at). Here are the partial emulation bindings I've come up with. To see how to extend these to do more, see my full article.

To use one of these, simply take the text file, and rename it to DefaultKeyBinding.dict, and then put it in the ~/Library/KeyBindings/ folder (where ~ stands for your home folder), which can be created if it doesn't already exist. Then relaunch your Cocoa applications, and enjoy some new key bindings.

Hint #2: Key bindings to do really freaking cool stuff

It is possible to do some really wacky things with these key bindings. They can save your document, select, move, and copy text, change your formatting, even use the speech synthesizer to say your text out loud. The full article explains the format in detail, but one of my favorite things the system can do is type arbitrary text. This allows common phrases or letters to be entered with one keystroke.

For instance, imagine that I type lots of HTML code, and I'm getting tired of typing <blockquote></blockquote>, <code></code>, and <div></div> over and over, etc. Instead, I want to type Shift-Control-H (for HTML), and have the word I just typed turned into such a tag. If I add the following text into my DefaultKeyBinding.dict file, I can do just that:

  {
      /* This command will let Ctrl-Shift-H turn the previous word
       * into an HTML/XML opening and closing tag pair. */
      "^H" = ( "setMark:",
               "moveWordBackward:",
               "deleteToMark:",
               "insertText:", "<",
               "yank:",
               "insertText:", ">",
               "setMark:",
               "insertText:", "</",
               "yank:",
               "insertText:", ">",
               "swapWithMark:"
              );
  }
After putting the above text in DefaultKeyBinding.dict, try relaunching TextEdit, or Mail, or Safari, and typing any word, followed by Shift-Control-H. Prepare to be amazed! There is much much more that can be done with bindings, but I'll let you read the article to find out about it. I've tried to make a complete list of the actions that can be used with key bindings, but I'm sure I missed a few.

Hint #3: Incremental Search

It is possible to get incremental search working in all Cocoa text fields. Camino and Firefox users should be familiar with this--the basic idea is that as you type a search, your program finds words that match, rather than needing to click an "okay" button.

To do this, install the Incremental Search Input Manager (direct link to a universal binary), which is an amazing free input manager from Michael McCracken. Then make a DefaultKeyBinding.dict file that looks like this:
  {
      /* Ctrl-S and Ctrl-R for incremental search */

      "^s" = "ISIM_incrementalSearch:";
      "^r" = "ISIM_reverseIncrementalSearch:";
      "^$g" = "abort:";
  }
Now just restart TextEdit, open a big text document, type ⌃S, and start typing a search. You'll never do Command-F again!

Hint #4: Repeat your keystrokes as many times as you like

Type the following command into the terminal:
  defaults write -g NSRepeatCountBinding -string "^u"
Now start up TextEdit, and type ⌃U, followed by a number, maybe 44 or something, and then any letter key. Here's what I get if I type ⌃U then 44 then Option-G:
  ©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©©
That's a lot of copyright signs--and 44 could just as easily be 84 or 144. If you want, you can make any keyboard shortcut be your "repeat count binding;" it doesn't have to be ⌃U. That's the traditional emacs shortcut, so it's what I use.

An old related hint:

The hint Enabling meta-key Emacs shortcuts in Cocoa apps from 2001 talked about putting in some emacs key bindings. Needless to say, there's a lot more that the system can do than that!

I hope you enjoy this hint, and the full article!

Comments (17)


Mac OS X Hints
http://hints.macworld.com/article.php?story=20060317045211408